Next available Date - ssas

I have a tubular model that has a standard star schema
On my dim date table there is a column that flags UK holidays
I would like to not included this date if a key chooses a date that has been flagged but the next availble date
I don't have much access to the database to build a function for this as Ive seen others do
Could anyone suggest some Dax or a method of doing this
Thanks so much in advance
sample

You can create a calculated column to get the next working dateKey if date is flagged as non working date. In case date is not flagged the column contains the dateKey value.
Use this DAX expression in the calculated column:
=
IF (
[isDefaultCalendarNonWorkingDay] = 1,
CALCULATE (
MIN ( [dateKey] ),
FILTER (
DimDate,
[dateKey] > EARLIER ( [dateKey] )
&& [isDefaultCalendarNonWorkingDay] = 0
)
),
[dateKey]
)
I've recreated you DimDate table with some sample data:
Let me know if this helps.

Related

Big query - Schedule Query on an external partitioned table with the keyword #run_date

Because it is client data I've replace in this post the project name and the dataset name by ******)
I'm trying to create a new schedule query in BigQuery on Google cloud platform
The problem is I've got this error in the web Query editor
Cannot query over table '******.raw_bounce_rate' without a filter over column(s) 'dt' that can be used for partition elimination
The thing is I do filter on the column dt.
Here is the scheme of my external partitioned table
Tracking_Code STRING
Pages STRING NULLABLE
Clicks_to_Page INTEGER
Path_Lengths INTEGER
Visit_Number INTEGER
Visitor_ID STRING
Mobile_Device_Type STRING
All_Visits INTEGER
dt DATE
dt is the field of the partition and I selected the option "Require partition filter"
Here is the simplify sql of my query
WITH yesterday_raw_bounce_rate AS (
SELECT *
FROM `******.raw_bounce_rate`
WHERE dt = DATE_SUB(#run_date, INTERVAL 1 DAY)
),
entries_table as (
SELECT dt,
ifnull(Tracking_Code, "sans campagne") as tracking_code,
ifnull(Pages, "page non trackée") as pages,
Visitor_ID,
Path_Lengths,
Clicks_to_Page,
SUM(all_visits) AS somme_visites
FROM
yesterday_raw_bounce_rate
GROUP BY
dt,
Tracking_Code,
Pages,
Visitor_ID,
Path_Lengths,
Clicks_to_Page
HAVING
somme_visites = 1 and Clicks_to_Page = 1
)
select * from entries_table
if I remove the statement
Clicks_to_Page = 1
or if I replace the
DATE_SUB(#run_date, INTERVAL 1 DAY)
by a hard coded date
the query is accepted by Big Query, it does not make sense to me
Currently, there is an open issue, here. It addresses the error regarding using #run_date filter in the filter of scheduled queries to partitioned tables with required filter. The engineering team is currently working on it, although there is no ETA.
In your scheduled query, you can use one of the two workarounds using #run_date.As follows:
First option,
DECLARE runDateVariable DATE DEFAULT #run_date;
#your code...
WHERE date = DATE_SUB(runDateVariable, INTERVAL 1 DAY)
Second option,
DECLARE runDateVariable DATE DEFAULT CAST(#run_date AS DATE);
#your code...
WHERE date = DATE_SUB(runDateVariable, INTERVAL 1 DAY)
In addition, you can also use CURRENT_DATE() instead of #run_date, as shwon below:
DECLARE runDateVariable DATE DEFAULT CURRENT_DATE();
#your code...
WHERE date = DATE_SUB(runDateVariable, INTERVAL 1 DAY)
UPDATE
I have set up another scheduled query to run daily with a table partitioned by DATE from a field called date_formatted and the partition filter is required. Then I have set up a backfill, here, so I could see the result of the scheduled query for previous days. Below is the code I used:
DECLARE runDateVariable DATE DEFAULT #run_date;
SELECT #run_date as run_date, date_formatted, fullvisitorId FROM `project_id.dataset.table_name` WHERE date_formatted > DATE_SUB(runDateVariable, INTERVAL 1 DAY)

How to Update end date by adding duration to start date SQL

As in title i don't know how to add duration (from the same table) to start date, to get end date in result, table is looks like:
create table NR1
(
id INTEGER not null,
price INTEGER,
price2 INTEGER,
start_date DATE,
end_date DATE,
duration NUMBER
)
i tried something like this, but i have some errors:
update nr1
set end_date =dateadd(MONTH, nr1.duration, nr1.start_date);
it should works, but i have problems with MONTH, at all SQL developer says that.
You probably need add_months:
update NR1
set end_date = add_months(start_date, duration)
You are using syntax form a different database platform. The Oracle equivalent is the add_months() function:
update nr1
set end_date = add_months(nr1.start_date, nr1.duration);
If you just add a plain number to a date that's treated as a number of (whole or partial) days. You can also use intervals (via numtodsinterval()) for other periods of time, but using that for months can be difficult.
Months and days are simple through the basic functionality and functions though.
If you're on a recent version of Oracle you should consider using a virtual column so you don't have to maintain both values.
These are perfectly working SQL statement.
SELECT DATEADD(HOUR, 5, '5:00');
SELECT DATEADD(MINUTE, 5, '5:00');
SELECT DATEADD(SECOND, 5, '5:00');
You can try queries here: W3Schools Link

DAX running total based on 3 columns, one of which is a repeating integer running total

Very new to DAX/PowerPivot, and faced with devilishly tricky question on day one.
I have some data (90,000 rows) I'm trying to use to calculate a cumulative fatigue score for folk working shifts(using PowerPivot/Excel 2016). As per the below screenshot, the dataset is shift data for multiple employees, that has a cumulative count of days worked vs. days off that resets back to 1 whenever they switch from one state to the other, and a 'Score' column that in my production data contains a measure of how fatigued they are.
I would like to cumulatively sum that fatigue score, and reset it whenever they move between the 'Days worked' and 'Days off' states. My desired output is in the 'Desired' column far right, and I've used green highlighting to show days worked vs. days off as well as put a bold border around separate Emp_ID blocks to help demonstrate the data.
There is some similarity between my question and the SO post at DAX running total (or count) across 2 groups except that one of my columns (i.e. the Cumulative Days one) is in a repeating sequence from 1 to x. And Javier Guillén's post would probably make a good starting point if I'd had a couple of months of DAX under my belt, rather than the couple of hours I've gained today.
I can barely begin to conceptualize what the DAX would need to look like, given I'm a DAX newbie (my background is VBA, SQL, and Excel formulas). But lest someone berate me for not even providing a starting point, I tried to tweak the following DAX without really having a clue what I was doing:
Cumulative:=CALCULATE(
SUM( Shifts[Score] ) ,
FILTER(Shifts,Shifts[Cumulative Days] <= VALUES(Shifts[Cumulative Days] )) ,
ALLEXCEPT( shifts, Shifts[Workday],Shifts[EMP_ID] ) )
Now I'll be the first to admit that this code is DAX equivelant of the Infinite Monkey Theorem. And alas, I have no bananas today, and my only hope is that someone finds this problem suitably a-peeling.
The problem with this table is there is no way to determine when stop summing while performing the cumulative total.
I think one way to achive it could be calculating the next first date where continuous workday status changes.
For example the workday status in the first three rows for EMP_ID 70073 are the same, until the fourth row, date 04-May which is the date the workday status changes. My idea is to create a calculated column that find the status change date for each workday serie. That column lets us implement the cumulative sum.
Below is the expression for the calculated column I named Helper.
Helper =
IF (
ISBLANK (
CALCULATE (
MIN ( [Date] ),
FILTER (
'Shifts',
'Shifts'[EMP_ID] = EARLIER ( 'Shifts'[EMP_ID] )
&& 'Shifts'[Workday] <> EARLIER ( 'Shifts'[Workday] )
&& [Date] > EARLIER ( 'Shifts'[Date] )
)
)
),
CALCULATE (
MAX ( [Date] ),
FILTER (
Shifts,
Shifts[Date] >= EARLIER ( Shifts[Date] )
&& Shifts[EMP_ID] = EARLIER ( Shifts[EMP_ID] )
)
)
+ 1,
CALCULATE (
MIN ( [Date] ),
FILTER (
'Shifts',
'Shifts'[EMP_ID] = EARLIER ( 'Shifts'[EMP_ID] )
&& 'Shifts'[Workday] <> EARLIER ( 'Shifts'[Workday] )
&& [Date] > EARLIER ( 'Shifts'[Date] )
)
)
)
In short, the expression says if the date calculation for the current workday series change returns a blank use the last date for that EMP_ID ading one date.
Note there is no way to calculate the change date for the last workday serie, in this case 08-May rows, so if the the calculation returns blank it means it is being evaluated in the last serie then my expression should return the max date for that EMP_ID adding one day.
Once the calculated column is in the table you can use the following expression to create a measure for the cumulative value:
Cumulative Score =
CALCULATE (
SUM ( 'Shifts'[Score] ),
FILTER ( ALL ( 'Shifts'[Helper] ), [Helper] = MAX ( [Helper] ) ),
FILTER ( ALL ( 'Shifts'[Date] ), [Date] <= MAX ( [Date] ) )
)
In a table in Power BI (I have no access to PowerPivot at least eight hours) the result is this:
I think there is an easier solution, my first thought was using a variable, but that is only supported in DAX 2015, it is quite possible you are not using Excel 2016.
UPDATE: Leaving only one filter in the measure calculation. FILTER are iterators through the entire table, so using only one filter and logic operators could be more performant.
Cumulative Score =
CALCULATE (
SUM ( 'Shifts'[Score] ),
FILTER (
ALL ( 'Shifts'[Helper], Shifts[Date] ),
[Helper] = MAX ( [Helper] )
&& [Date] <= MAX ( [Date] )
)
)
UPDATE 2: Solution for pivot tables (matrix), since previous expression worked only for a tabular visualization. Also measure expression was optimized to implement only one filter.
This should be the final expression for pivot table:
Cumulative Score =
CALCULATE (
SUM ( 'Shifts'[Score] ),
FILTER (
ALLSELECTED ( Shifts ),
[Helper] = MAX ( [Helper] )
&& [EMP_ID] = MAX ( Shifts[EMP_ID] )
&& [Date] <= MAX ( Shifts[Date] )
)
)
Note: If you want to ignore filters use ALL instead of
ALLSELECTED.
Results in Power BI Matrix:
Results in PowerPivot Pivot Table:
Let me know if this helps.

SQL Aggregation / Window Function for Summarizing Data

I would like to create a query to do the following but I am having trouble:
I have a DB table with the columns:
TestYear (int, e.g. 2014)
Date (date, i.e. set of dates in a given year)
DailyWorstValue
RunningValue
Primary key is TestYear + Date
I would like to get the:
LAST RunningValue ordered by Date (i.e. the final value)
MINIMUM WorstValue (i.e. the worst value)
Per TestYear
This will basically be a one-row summary per TestYear. Is it possible to do this using window functions? Thank you very much in advance for any help that you can give.
Am not sure why you need window function to do this just aggregate function will do the job for you
SELECT testyear,
MIN_DailyWorstValue = Min(dailyworstvalue),
RV.last_runningvalue
FROM db_table A
CROSS apply (SELECT TOP 1 Last_RunningValue= runningvalue
FROM db_table B
WHERE A.testyear = B.testyear
ORDER BY date DESC) RV
GROUP BY testyear,
RV.last_runningvalue

Filter data based on date provided by user

I have a SQL query as shown below:-
select *
from dbo.NGPTimesheetsPosition
where ProjectNO = '12169-01-c' AND CreditorEmployeeID <> 'E0000' AND DocType = 'Time Sheet'
This returns the below data:
What I want to do is be able to show only data up to and including a user defined date e.g. 01/02/2013.
User defined date could be anything up to the current month.
All help or advice much appreciated.
You'll need to add a parameter to your report, and use this parameter in your dataset query along these lines:
SELECT *
FROM dbo.NGPTimesheetsPosition
WHERE ProjectNO = '12169-01-c'
AND CreditorEmployeeID <> 'E0000'
AND DocType = 'Time Sheet'
AND TransactionDate <= #MyDateParameter -- ADDED!
You're not entirely clear in your question about possible values for the parameter, when you state:
User defined date could be anything up to the current month.
I think these folks at SqlServerCentral are right: you can't set limits for a data parameter. This leaves you with two basic options:
Let it be. If needed you can add a AND #MyDateParameter <= CURRENT_TIMESTAMP clause to your query.
Populate a dataset with available dates, and use those as available values for your parameter
select *
from dbo.NGPTimesheetsPosition
where ProjectNO = '12169-01-c' AND CreditorEmployeeID <> 'E0000' AND DocType = 'Time Sheet'
and TransactionDate <= '2013-02-01'
?
In your where clause do date comparison like below
Convert( varchar (11) , transactiondate , 101 ) <= '01/02/2013'