MDX Filter date less than today - reporting-services

I want to filter my query in a data set in a way, where I got dates from beginning of the month until yesterday. First part is easy, I'm passing month from report parameters, so I got values from every day in month, but somehow I have to limit this until yesterday. I tried putting this expression in where clause, but it didn't work at all since I don't have date on rows: FILTER([Date of shipment].[Date], [Date of shipment].[Date] < Format(Now(), "yyyyMMdd").
I know I could filter rows, but important thing is, I don't want Date to be displayed on the rows.
Edit: additionally I can use parameter supplied by main report, which is yesterday's date. But how do I limit date without putting it on rows? Something like this doesn't works: IIF( STRTOSET(#ShipmentDate, CONSTRAINED).Count = 1, STRTOSET(#ShipmentDate, CONSTRAINED), [Shipment Date].[Date] < #ShipmentDate))

You already have something similar to this:
SELECT
{} ON 0
,
[Date].[Calendar].[Date].&[20050101]
:
StrToMember
('[Date].[Calendar].[Date].&[20050105]' //<<hard-coded to illustrate
,constrained
) ON 1
FROM [Adventure Works];
Returns:
Most cubes have a multi-level date hierarchy - so you could change your code to something like the so that next year you do not need to change the hard-coded bit:
SELECT
{} ON 0
,
Descendants
(
Exists
(
[Date].[Calendar].[Calendar Year].MEMBERS
,StrToMember
(#ShipmentDate
,constrained
)
).Item(0)
,[Date].[Calendar].[Date]
).Item(0)
:
StrToMember
(#ShipmentDate
,constrained
) ON 1
FROM [Adventure Works];
If #ShipmentDate is set to '[Date].[Calendar].[Date].&[20060105]' then I get the following:

Solution:
Since I had Month passed through parameter dates were limited to current month. This allowed me to do this:
[Shipment date].[Datw].&[20160101] : STRTOMEMBER(#ShipmentDate, constrained)
Way I did this is ugly, but it works(it may need mainteance, to change date to 20170101 in next year and so on).

Related

SSRS Filter Expression by date range

I have an expression that outputs the number of rows: =CountRows("DataSet1").
I want to filter it by date range using parameters in order to output the number of rows within that range.
I have tried this: =CountRows(IFF Fields!DATE_OF_REQUEST.Value, "DataSet1" >= Parameters!startDate.Value
AND Fields!DATE_OF_REQUEST.Value, "DataSet1" <= Parameters! endDate.Value
("DataSet1"))
How can I achieve the desired output?
Probably not the most efficient solution, but, is the way I go about making date range reports:
I would apply the date range in the where clause of your dataset:
WHERE Date_of_Request between #startDate and #endDate
For this, I would create another identical dataset that just looks at distinct records and apply the where clause to get the most accurate figure.
I'm assuming the logic in your COUNTROWS expression is correct here...
What you need to do is evaluate each row and if it matches you criteria return 1 else return 0 then sum the results of this. So you can modify you expression slightly like this.
=SUM(
IIF(
Fields!DATE_OF_REQUEST.Value >= Parameters!startDate.Value
AND Fields!DATE_OF_REQUEST.Value <= Parameters!endDate.Value,
1,
0,
"DataSet1"
)
)
I'm doing this from memeory so the position of the scope "DataSet1" might be incorrect.

SSRS - How do I format SQL data to generate line chart of time series?

I have a table that is set up like
SELECT [EntryDate] --Date
,[StoreId] --Nvarchar
,[PassFailElement] --Int, 1 or 0
And the SSRS report is set up for the user to input #StartDate and #EndDate to bookend the [EntryDate]s they want to see.
Is there a way to create a line graph that shows the values for [PassFailElement] from #StartDate to #EndDate as the first series, DateAdd(DateInterval.Year,-1,#StartDate) to DateAdd(DateInterval.Year,-1,#EndDate) for the second series, and then two years back for the third series?
I'm sure there are a million more elegant ways to do this but here is how I might approach it...
The following is based on the Microsoft supplied NorthWind database so you can recreate it if you really want to...
I've set the actual start and end date values in here but you can comment out the first few lines and then your SSRS parameters will be applied.
So to start with a took the orders table as it had some dates in and joined to some basic order data just so I could see the results looked OK, most of the columns are not used.
My dataset looks like this...
SET DATEFORMAT YMD
DECLARE #startDate date = '1998/04/01'
DECLARE #endDate date = '1998/07/30'
SELECT
e.EmployeeID, e.FirstName, e.LastName, e.Title
, o.OrderID, o.OrderDate
, c.CustomerID, c.CompanyName
, CASE
WHEN (OrderDate between #startDate and #endDate ) THEN 'This Year'
WHEN (OrderDate between dateadd(YYYY,-1,#startDate) and dateadd(YYYY,-1,#endDate )) THEN 'Last Year'
WHEN (OrderDate between dateadd(YYYY,-2,#startDate) and dateadd(YYYY,-2,#endDate )) THEN '2 Years ago'
END as YearGroup
, MONTH(OrderDate) AS OrderMonth
, Day(OrderDate) AS OrderDay
FROM Employees e
join Orders o on e.EmployeeID = o.EmployeeID
join Customers c on o.CustomerID = c.CustomerID
WHERE
(OrderDate between #startDate and #endDate ) OR
(OrderDate between dateadd(YYYY,-1,#startDate) and dateadd(YYYY,-1,#endDate )) OR
(OrderDate between dateadd(YYYY,-2,#startDate) and dateadd(YYYY,-2,#endDate ))
The Case statement in the SELECT clause checks to see if the dates fall into one of three groups, either
between the start and end dates supplied
between the same date range but minus a year
between the same date range but minus two years
The computed OrderMonth and OrderDay are there as I assume you will want to 'stack' the lines so say, 1 June, across all three groups is in the same horizontal position on the chart. ** See notes later for changing this.
The WHERE clause does similar tests to make sure we only return data from the ranges we need.
All I did them was simply add a line chart and set
the Series Groups to the [YearGroup] field
the [OrderMonth] and [OrderDay] to the CategoryGroup
and (for no other reason than I didn't have much else to display) I used the sum of OrderID as the values.
** if you want to represent the time range as one continuous time, then remove the OrderMonth and OrderDay from the category groups and replace with OrderDate
The resulting chart looked awful but that was just down to the data.
I would create a couple of Calculated Fields in your dataset to break up the data and add them to the chart.
The first would be a field that determines which year the data is in - Current, Previous or the Prior. Maybe just 0, 1 or 2? This field would be used as your chart series. Call it ENTRY_YEAR.
The second would be a date field with the years all set to the current year. You could just add the integer from the first field. This will normalize all your data to a single year timeline. You won't actually use the year - that's just to separate the data at the year break.
=DATEADD("y", ENTRY_YEAR, Fields!EntryDate.Value)

SQL query to select values grouped by hour(col) and weekday(row) based on the timestamp

I have searched SO for this question and found slightly similar posts but was unable to adapt to my needs.
I have a database with server requests since forever, each one with a timestamp and i'm trying to come up with a query that allows me to create a heatmatrix chart (CCC HeatGrid).
The sql query result must represent the server load grouped by each hour of each weekday.
Like this: Example table
I just need the SQL query, i know how to create the chart.
Thank you,
Those looks like "counts" of rows.
One of the issues is "sparse" data, we can address that later.
To get the day of the week ('Sunday','Monday',etc.) returned, you can use the DATE_FORMAT function. To get those ordered, we need to include an integer value 0 through 6, or 1 through 7. We can use an ORDER BY clause on that expression to get the rows returned in the order we want.
To get the "hour" across the top, we can use expressions in the SELECT list that conditionally increments the count.
Assuming your timestamp column is named ts, and assuming you want to pull all rows from the year 2014, we start with something like this:
SELECT DAYOFWEEK(t.ts)
, DATE_FORMAT(t.ts,'%W')
FROM mytable t
WHERE t.ts >= '2014-01-01'
AND t.ts < '2015-01-01'
GROUP BY DAYOFWEEK(t.ts)
ORDER BY DAYOFWEEK(t.ts)
(I need to check the MySQL documentation, WEEKDAY and DAYOFWEEK are real similar, but we want the one that returns lowest value for Sunday, and highest value for Saturday... i think we want DAYOFWEEK, easy enough to fix later)
The "trick" now is the columns across the top.
We can extract the "hour" from timestamp using the DATE_FORMAT() function, the HOUR() function, or an EXTRACT() function... take your pick.
The expressions we want are going to return a 1 if the timestamp is in the specified hour, and a zero otherwise. Then, we can use a SUM() aggregate to count up the 1. A boolean expression returns a value of 1 for TRUE and 0 for FALSE.
, SUM( HOUR(t.ts)=0 ) AS `h0`
, SUM( HOUR(t.ts)=1 ) AS `h1`
, SUM( HOUR(t.ts)=2 ) AS `h2`
, '...'
, SUM( HOUR(t.ts)=22 ) AS `h22`
, SUM( HOUR(t.ts)=23 ) AS `h23`
A boolean expression can also evaluate to NULL, but since we have a predicate (i.e. condition in the WHERE clause) that ensures us that ts can't be NULL, that won't be an issue.
The other issue we can encounter (as I mentioned earlier) is "sparse" data. To illustrate that, consider what happens (with our query) if there are no rows that have a ts value for a Monday. What happens is that we don't get a row in the resultset for Monday. If it does happen that a row is "missing" for Monday (or any day of the week), we do know that all of the hourly counts across the "missing" Monday row would all be zero.

MySQL: BETWEEN .. how to check for a range?

i need to write a query for the following situation:
3 columns: "box", "in", "out" (box is an integer, in and out are dates)
i need something to test if from the "in" date to the "out" date (the period between these dates), a certain box id number has been given already.
i thought to do something like:
SELECT COUNT(*) FROM `tbl` WHERE `box` = '#' AND ***period*** BETWEEN 'date1' AND 'date2'
(i know BETWEEN doesn't work this way (link), but it was just to give you an idea...)
period = the new dates that i'm tryin to register in the database
so, if the query returns '0' i know i can assign this box # in those dates, if not i know i can't. i'm stucked here since last week!! X(
I think you want either:
SELECT COUNT(*) FROM tbl WHERE box = '#' AND
`in` =< 'date1' AND out >= 'date1'
OR `in` =< 'date2' AND out >= 'date2'
or
SELECT ... AND
period BETWEEN `in` AND out

Date range issue in MDX with missing dates

I have an SSRS report which gets filtered with the following expression:
="{[Claim Cheque].[Cheque Date].&[" + format(Parameters!StartDate.Value, "yyyy-MM-dd") + "T00:00:00]:[Claim Cheque].[Cheque Date].&[" + format(Parameters!EndDate.Value, "yyyy-MM-dd") + "T00:00:00]}"
which works fine. My problem is I don't have cheques everyday and this makes the query return no results. As an example I'm choosing the date range from 1st to 20th of November. I have cheques in 14th and 15th but NOT 20th. I will miss 14th and 15th results in my report this way.
I know how to force the parameters to get only existing values in the cube. but I need to be able to select all dates. Is there any other way to make this expression return desired results?
Any help is appreciated.
It looks to me like you have a separate date dimension just for [Cheque Date], rather than linking back to a fully populated master date dimension. Take a look at the way Order Date and Ship Date dimensions are done in the AdventureWorks sample. They are explained nicely here: Role-playing dimensions
I was able to run MDX queries like yours against that data, where there were no transactions on the start and end dates of the range:
Select
[Measures].[Order Count] on 0,
[Sales Channel].&[Reseller] on 1
From [Adventure Works]
Where {[Ship Date].[Fiscal].[Date].&[20060701]:[Ship Date].[Fiscal].[Date].&[20060710]}
and
Select
[Measures].[Order Count] on 0,
([Sales Channel].&[Reseller],
{[Ship Date].[Fiscal].[Date].&[20060701]:[Ship Date].[Fiscal].[Date].&[20060710]}) on 1
From [Adventure Works]