We are building a cube for the business who analyse Sales against Stock.
I need a separate measure which will show the Closing Stock Qty.
The business runs in retail periods which contain retail weeks. The week always finishes on a Sunday, so my closing stock quantity needs to be from the Sunday.
So if we are looking at sales against today (Tuesday, 12th July 2016), then the column should show the value for the Sunday just passed, which is Sunday, 10th July 2016.
This needs to be dynamic depending on the level the user is viewing the data at.
If the lowest level is shown at the day level, then for all days for that week, it should show the previous Sunday's value.
If the lowest level is shown at the week level, then each week should show the previous weeks closing balance
Etc
, if the user is not breaking the pivot table down by date, but just retail weeks, then it should show the value for the last day of the previous week.
Same rules if the user was breaking the pivot table down to the level of period- it should show the value for the last day of the previous
We have a Date dimension with the following relevant hierarchies:
Calendar
Calendar Year
Calendar Quarter
Calendar Month
Date
Retail
Retail Year
Retail Period
Retail Week
Date
I know I can use ClosingPeriod function for this but I am having trouble with the Syntax.
I have the below but am getting NULL's. This is my first real MDX calculation so very new to this!
WITH MEMBER [Measures].[Closing On Hand Qty] AS
(
ClosingPeriod(
[Date].[Retail].[Retail Week],
[Date].[Retail].CurrentMember
),
[Measures].[On Hand Qty]
)
SELECT
[Date].[Retail].[Date].Members ON ROWS,
{
[Measures].[On Hand Qty],
[Measures].[Closing On Hand Qty]
} ON COLUMNS
FROM
Retail
WHERE
[Date].[Retail Year].&[2017]
(note: it doesn't throw an exception but the mdx standard is to state columns before rows in the Select clause)
ClosingPeriod I've not played with but something like the following might help:
WITH
MEMBER [Measures].[Closing On Hand Qty] AS
(
TAIL(
DESCENDANTS(
EXISTING [Date].[Retail].[Retail Week],
[Date].[Retail].[Date]
)
).ITEM(0).ITEM(0)
,[Measures].[On Hand Qty]
)
SELECT
{
[Measures].[On Hand Qty],
[Measures].[Closing On Hand Qty]
} ON 0,
[Date].[Retail].[Date].MEMBERS ON 1
FROM Retail
WHERE [Date].[Retail Year].&[2017];
Looking at the docs for ClosingPeriod I think something like the following might work:
WITH MEMBER [Measures].[Closing On Hand Qty] AS
(
ClosingPeriod(
[Date].[Retail].[Date],
EXISTING [Date].[Retail].[Retail Week]
),
[Measures].[On Hand Qty]
)
SELECT
{
[Measures].[On Hand Qty],
[Measures].[Closing On Hand Qty]
} ON COLUMNS,
[Date].[Retail].[Date].Members ON ROWS
FROM Retail
WHERE [Date].[Retail Year].&[2017];
Related
I have a table (holidays) containing all the holidays in a year:
I need to make a table (t1) where 1 column contains all the 365 days within a year, and another column 'description' containing a name of a holiday for all dates that are within a +/- 7 day range of a holiday, and 'None' for all dates that are outside of this range.
I was able to use generate_series to create the first-column (my_date: all 365 days within a year) and used a left-join to try to create the second column (description)
WITH all_dates AS
SELECT my_date::date
FROM generate_series('2020-01-01', '2020-12-31', '1 day'::interval) my_date)
SELECT all_dates.my_date,
holidays.description
FROM all_dates
LEFT JOIN holidays
ON all_dates.my_date = holidays.holiday_date
To create the table below.
However, I need it to be such that 2020-01-02, 2020-01-02, ..., 2020-01-08 would have the description 'New Year's Day' as these dates are within a 7-day range of New Year's Day, and so forth for other days within a 7-day range of other holidays (e.g., rows for dates between 2020-12-18 to 2020-12-31 would have the description 'Christmas')
I'm also unsure about how to handle days that are within a 7-day range of more than one holiday (Father's Day and Independence Day have overlapping dates that are within a 7-day range). I need it to be such that there is only one row per day in 2020.
Any help would be appreciated!
Try something like below. You already have the ranges around the holidays, so use that in the join. Then, use distinct on to restrict results to one per calendar date, and adjust the order by to keep the holiday you want.
with all_dates as (
select my_date::date
from generate_series('2020-01-01',
'2020-12-31', '1 day'::interval) my_date
)
select distinct on (all_dates.my_date)
all_dates.my_date,
holidays.description
from all_dates
left join holidays
on all_dates.my_date
between holidays.holiday_date_min7
and holidays.holiday_date_plus7
order by all_dates.my_date,
abs(all_dates.my_date - holidays.holiday_date), -- keep closest
all_dates.my_date - holidays.holiday_date -- prefer upcoming holiday
I am trying to calculate a measure which is the difference between a measure (say, profit) today and the nearest preceding quarter.
E.g.: if the quarter months are March, June, September and December, then:
If the current month is May, then the calculated measure = Profit(May)-Profit(March)
If the current month is November, then the calculated measure = Profit(November)-Profit(September)
If the current month is December, then the calculated measure = Profit(December)-Profit(September)
I'm new to MDX and would really like some help on this.
I'm aware of .CurrentMember.PrevMember to get the previous member, but that doesn't help if you don't know how many previous members calls you should use.
Welcome to MDX. To solve the problem you need to have basic understanding of "User Hierarchy".Plus you should know how the functions "currentmember", "parent", "lag()" and "lastchild".
Based on this follow the example below. I am trying to re-produce your example on AdventureWorks for year 2013.
Lets first see all the internet sales amount for 2013
select
{[Measures].[Internet Sales Amount]}
on columns,
{
[Date].[Month of Year].[Month of Year]
}
on rows from
[adventure works]
where
[Date].[Calendar Year].&[2013]
Result
Now lets make a measure that will result value for the last month of previous quater
with
member [Measures].[LastMonthOfPreviousQuater] as
([Date].[Calendar].currentmember.parent.lag(1).lastchild,
[Measures].[Internet Sales Amount])
select
{[Measures].[Internet Sales Amount],[Measures].[LastMonthOfPreviousQuater]}
on columns,
{
[Date].[Calendar].[Month].&[2013]&[09]
}
on rows from
[adventure works]
Result
I have a table of sales grouped by week. I want to write a query that creates a new table giving the sales of the week in question AND the sales of that item from this time last year, but my attempts either give blank cells for the this-time-last-year (TTLY) values or duplicates.
I've tried writing a subquery that takes the date, subtracts 52 weeks, and shows the value for that week, then joining that subquery to my main query.
However, that subquery isn't working: the query shows the date of a year ago correctly, but doesn't then pull the SALES for that TTLY week, only the current week.
with ttyl as
(select
date::date as date,
(sales.date - interval '52 weeks') as date_ttly,
ID,
value
from sales
where country = 'uk' and date > '2019-08-01' and ID = '12345678')
In this example the subquery generates the previous year's date in the date_ttly column but pulls 2019 data in the value column.
All the WHERE conditions are just temporary so as to make building the query easier.
Thank you!
Assuming that the sales are grouped by date and by country only, a join on the same table should work:
SELECT sales1.id,
sales1.date,
sales1.value,
sales2.date,
sales2.value
FROM sales AS sales1
JOIN sales AS sales2 ON sales1.date - interval '52 weeks' = sales2.date
AND sales1.country = sales2.country
However, this also assumes that your date is always the same day of the week, e.g. Monday.
I have 3 tables, one with stocktakes conducted last year, one with stocktakes conducted this year and one with sales. All of them are joined by date to one table where I have dates.
Now the question is what can I do to get table with:
store name/ last year stocktake date/ this year stocktake date/ sum of sales from last year stocktake date to this year stocktake date.
If you choose store, than stocktake date from one table, stocktake from second table all looks good, the problem is that I can't get sales to show from/to.
C2Csales = calculate(sum(PP_SalesLessTax[SalesLessTax]),PP_SalesLessTax[date] >= [ly date])
[ly date] is just a measure with last year stocktake date
I have a feeling that this have to be very easy but have no idea how to get this work
thanks
daniel
please see data model. It is a part of bigger model but I have trimmed it so it is clear what is this about.
data model
And here is what I need. Please see picture.
thanks for all responses
result required
You don't need two tables to simulate years. You can have just one. The idea of last year should be calculated by a measure. If you have a complete date table with a day for each row without missing days then you can build time intelligence.
If I get you, you need something like this two measures:
Sales = sum(PP_SalesLessTax[SalesLessTax]
Sales LY = CALCULATE ( sum(PP_SalesLessTax[SalesLessTax] , SAMEPERIODLASTYEAR ( DatesTable[DateColumn] )
With this two measures you can take both of them on same visualizations to compare them.
The idea of having from and to can be solved on visualizations. The slicer with a date type column can create a range filter data that will apply for this two created measures.
I use tsql to sum weekly data (starting date is Monday).
Last week spanned across the boundary of 2012 and 2013, which means that I get two weekly sums.
Is there a way to group the data within tsql so I get one weekly sum for 2012-12-31 to 2013-01-06?
Example data and sql:
http://sqlfiddle.com/#!6/52b25/13/0
No link example below. Hypothetical table has one column, "created" of datetime type. How many rows for each week? I'd like to get two result rows, one for the last solid week of 2012 and one for the week that 2013 starts in (which starts on Monday 12/31/2012).
select
min(created) as 'First Date',
count(*) as 'Count',
datepart(wk,created) as 'Week Number'
from items
group by datepart(wk,created), datepart(yy,created)
order by min(created)
One workaround is calculate week number manually
select
min(created) as 'First Date',
count(*) as 'Count',
datediff(dd,'2012-01-02',created)/7 AS week_number
from items
group by datediff(dd,'2012-01-02',created)/7 -- You may replace '2012-01-02' to any date that is Monday (start day of the week)
order by min(created)