Setting 2 parameters with single dataset in SSRS - reporting-services

I've created a view that has 3 columns:
label
start_date
end_date
For example (if today is 2018-04-11 10:12:54.4770000):
Current Day, 2018-04-11 00:00:00.0000000, 2018-04-12 00:00:00.0000000
Prior Day, 2018-04-10 00:00:00.0000000, 2018-04-11 00:00:00.0000000
Last Week, 2018-04-02 00:00:00.0000000, 2018-04-09 00:00:00.0000000
Last 7 Days (rolling), 2018-04-04 00:00:00.0000000, 2018-04-11 10:12:54.4770000
Last Month, 2018-03-01 00:00:00.0000000, 2018-04-01 00:00:00.0000000
Last Quarter, 2018-01-01 00:00:00.0000000, 2018-04-01 00:00:00.0000000
Last Year, 2017-01-01 00:00:00.0000000, 2018-01-01 00:00:00.0000000
WTD, 2018-04-08 00:00:00.0000000, 2018-04-11 10:12:54.4770000
MTD, 2018-04-01 00:00:00.0000000, 2018-04-11 10:12:54.4770000
QTD, 2018-04-01 00:00:00.0000000, 2018-04-11 10:12:54.4770000
YTD, 2018-01-01 00:00:00.0000000, 2018-04-11 10:12:54.4770000
Last 30 Days (rolling), 2018-03-12 00:00:00.0000000, 2018-04-11 10:12:54.4770000
Last 90 Days (rolling), 2018-01-11 00:00:00.0000000, 2018-04-11 10:12:54.4770000
Last 365 Days (rolling), 2017-04-11 00:00:00.0000000, 2018-04-11 10:12:54.4770000
And so on. So my goal is to provide user dropdown with the labels displayed and when he picks any, I would like to assign #start_date and #end_date parameters to use in other datasets. Any suggestions what can I do?

Add a dataset called say dsDropDown and set the query to something like
SELECT * FROM myView
Add a parameter myParameter to your report and set the available values to your dsDropDown dataset. As you don't have a key you'll need to set the Value and Label properties both to your label field.
Next, add your main dataset and join to your view, filtering by the view label, something like.
SELECT *
FROM myTable t
JOIN myView v on t.SomeDate >= v.start_date AND t.SomeDate <= v.end_date
WHERE v.label = #myParameter
Make sure the parameter name in the dataset query matches the parameter name EXACTLY (they are case sensitive).
Next just add your tablix/matrix/chart etc and point it to your main dataset.
I think that should be it but this was off the top of my head so it may not be 100% correct. Hopefully enough for you to follow though.
Update after OP response:
If you need these are parameters then you will need to add two new datasets, dsStart and dsEnd. The query for these datasets will be as follows..
SELECT start_date from myView WHERE label = #myParameter
and
SELECT end_date from myView WHERE label = #myParameter
Then add two new parameters #start' and#end` and set the default values to the respective datasets.
When you select your first parameter, the seconds two will be updated automatically. You can set the #start and #end parameters to hidden once you confirm its working.
Then change the main dataset query to something like..
SELECT *
FROM myTable t
WHERE t.Somedate between #start AND #end

I'll answer my own question. "Alan Schofield" version works, but I wanted to do it with single dataset. So, what I did:
Added concatenated column to dataset that have start and end dates in it, for example: "2018-04-11 00:00:00.0000000|||2018-04-12 00:00:00.0000000"
Create 2 internal params with default value as =Split(Parameters!date_selector.Value,"|||")(0) and =Split(Parameters!date_selector.Value,"|||")(1) accordingly
That's it

Related

How to hide SubTotal Column if the month is not full solar Month in a range of dates

In a CashFlow Report I created a tablix with TransactionDate column that is filled with a range of #stardate and #enddate parameters. If the user selects for example:
#stardate='2020-01-01'
#enddate='2020-03-02'
I need to create dynamicaly the month subtotal, but only if the month is full solar month (days from 1 to 31) in the selected range. In the image sample the subtotal of January and February must be visible and the subtotal of March must be hidden.
Any suggestions?
Thanks
Hawa
sample image
The first thing I would do is create a table that contains dates. There are lots of examples out there on how to do this such as this
https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/
Assuming you now have a dates table with at least the following data available
TheDate TheMonth TheYear
2020-01-01 1 2020
2020-01-02 1 2020
...
2020-01-31 1 2020
2020-02-01 2 2020
...
2020-12-31 12 2020
...
and so on...
You can now get a simple list of last dates of the month
CREATE VIEW LastMonthDates AS
SELECT TheYear, TheMonth, MAX(TheDate) AS LastDate
FROM myDatesTable
GROUP BY TheYear, TheMonth
This will give us
TheYear TheMonth LastDate
2020 1 2020-01-31
2020 2 2020-02-29
...
and so on.
If you join this to your main data and add the LastDate column to your dataset query results, so the results are something like
Cluster1 Cluster2 TransDate Amount LastDate
Ins ROW1 2020-02-28 221.35 2020-02-29
Your topmost column group hidden property would then be something like
=MAX(Fields!TransDate.Value, "MonthColumGroup") <> FIRST(Fields!LastDate.Value, "MonthColumGroup")
So, if the highest date within the month group is not the same as the lastdate columne within the same monthgroup then hidden will be True
Change "MonthColumGroup" to the actual name of your outer month group, it has to be in quotes and is case sensitive.
If you have problems doing this (the grouping could cause issues) You could do that same thing in your dataset query by extend the it to have a column that does the same kind of test and simply sets it 1 or 0 depending on whether the month is complete or not.

MySQL, grouping by and performing a SUM within the groups

The table below contains records of shifts which have taken place. The start and end fields are the start and end timestamps of those shifts. I'm looking to build a query that will extract the total hours per month that the shifts cover.
Example table:
ID Start End
1 2018-10-23 10:30:00 2018-10-23 11:45:00
2 2018-10-22 22:00:00 2018-10-22 23:00:00
3 2018-11-22 22:00:00 2018-11-22 23:00:00
The ideal output would read:
Month Hours
10 2:15
11 1:00
I've got some of the elements worked out, using a SUM(timediff(end,start)) and GROUP BY, but havn't managed to get something good out!
Thanks!
Here you go:
select
month(start) as month,
time_format(sec_to_time(
sum(timestampdiff(second, start, end))
), '%H:%i') as hours,
sum(timestampdiff(second, start, end)) as seconds
from shift
group by month(start)
Result:
month hours seconds
----- ----- -------
10 02:15 8,100
11 01:00 3,600
Note: I added the extra column seconds in case you want to use this numeric value to do some extra processing.

MySQL Multiple Group by with Dates

I have the following Database with example content:
Now I want for a certain siteid for every weekday (Monday, ..., Sunday) for every tsegment-TIME (date independend) on this day the average category.
I have to parse the date from tstamp or tsegment. That basically work.
Then I have to parse the time - that does not work. Don't know why.
I surmise it is because of the group by Weekday. But I do not know how to solve it.
That is my query:
SELECT
siteid,
DAYNAME(STR_TO_DATE(tstamp, "%Y-%m-%d")) as Day,
STR_TO_DATE(tsegment,'%h:%i:%s') as Segment,
AVG(category)
FROM `ITODDB_Occupancy`
WHERE siteid = 350
GROUP BY
Segment, Day
The result is
I want output like this:
siteid Day Segment AVG(Category)
350 Monday 11:10:00 3.987
350 Monday 11:15:00 2.123
350 Tuesday 08:00:00 3.999
350 Tuesday 09:35:00 2.500
... ... ... ...
350 Sunday 03:45:00 1.432
350 Sunday 03:55:00 1.555
From what I've seen and worked with, the TIMESTAMP type can be somewhat wonky with STR_TO_DATE. Instead, use a combination of FROM_UNIXTIME/DATE_FORMAT
DATE_FORMAT(FROM_UNIXTIME('2016-01-20T11:30:20'), '%h:%i:%s')
That should give you what you need.
Example:
SELECT
siteid,
DAYNAME(STR_TO_DATE(tstamp, "%Y-%m-%d")) as Day,
DATE_FORMAT(FROM_UNIXTIME(tsegment), '%h:%i:%s') as Segment,
AVG(category)
FROM `ITODDB_Occupancy`
WHERE siteid = 350
GROUP BY
Segment, Day

How to get all rows where date is in a specific range at a given period?

How can I select all rows from a table where a date column is within a specific range of dates, at a given period (e.g. every 14 days)?
The table has a date column with most every date represented, possibly multiple times. The range is defined by a start date and an end date. The period is a number of days. For example:
Start: 2016-01-01 (friday)
End: 2016-12-31 (saturday)
period: 14 (days)
For the above, the query should return rows for every other Friday in 2016. That is, it should return the rows for the following dates:
2016-01-01
2016-01-15
2016-01-29
2016-02-12
2016-02-26
2016-03-11
2016-03-25
2016-04-08
2016-04-22
2016-05-06
2016-05-20
2016-06-03
2016-06-17
2016-07-01
2016-07-15
2016-07-29
2016-08-12
2016-08-26
2016-09-09
2016-09-23
2016-10-07
2016-10-21
2016-11-04
2016-11-18
2016-12-02
2016-12-16
2016-12-30
Currently, this is done in a stored procedure where a loop fills a temp table with the target dates, which is later joined on. However, I am trying to rewrite this code to step away from stored procedures.
What would be the best way to get the desired rows without using the stored procedure & a temp table? Keep in mind that (one of) the table(s) is quite large at around 1M records indexed on date, so any calculated values might impact the performance severely.
Alternatively, I could calculate all dates in the interval in PHP/RoR and use a massive IN clause, but hopefully there is a better solution.
Try this:
table_name1 is your table
date1 the date field
"2022-01-02" the start (twice included)
"2022-01-10" the end
3 the interval
SELECT date1
FROM table_name1
WHERE date1 BETWEEN "2022-01-02" AND "2022-01-10"
AND (DATE("2022-01-02") - date1) % 3 = 0;
Tested it with MySQL 5.6.

MYSQL Queries to find immediate next DateTime

I was writing a mini scheduler that perform certain task.
For calculating trigger time, I am using MYSQL. I am stucked at writing one of the query.
Find immediate DateTime which is greater than the given prevtime,
AND
the Day of the required immediate datetime should be ANY of given days
AND
time(HH:MM:SS) portion of required immediate datetime should be equal to given time.
Examples:
(a)
If given days are ('MON', 'WEDNES', 'SAT'),
given time is 10:15:00,
given prevtime is 2014-11-12 23:17:00
Then MYSQL should return
2014-11-15 10:15:00
(b)
Given Days: ('SUN','SAT','TUES')
Given Time: 09:10:00
Given prevtime is 2014-11-30 07:05:12
MYSQL should return 2014-11-30 09:10:00
(c)
Given Days: ('MON','THURS','SAT')
Given Time: 11:00:00
Given prevtime is 2014-12-29 11:55:12
MYSQL should return 2015-01-01 11:00:00
(d)
Days: (SUN, THURS, SAT)'
Given prevtime is 2014-02-27 18:15:00
Given Time 15:15:00
MYSQL Query result: 2014-03-01 15:15:00
(e)
DAYS: (TUES, WED, FRI)
Prev Date: 2014-12-23 09:30:00
Time : 08:00:00
Expected Result:
2014-12-24 08:00:00
(f)
DAYS: SUN, TUES, THURS
Prev Date: 2014-07-31 10:10:00
Time: 06:07:08
Expected Res:
2014-08-03 06:07:08
Using numeric weekday numbers, 0=Monday, 6=Sunday:
set #day1=0;
set #day2=2;
set #day3=5;
set #time=time('10:15:00');
set #prevtime=timestamp('2014-11-12 23:17:00');
select if(weekday(#nexttime:=date_add(concat(date(#prevtime),' ',#time),interval if(#time>time(#prevtime),0,1) day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,if(weekday(#nexttime:=date_add(#nexttime,interval 1 day)) in (#day1,#day2,#day3),#nexttime,date_add(#nexttime,interval 1 day))))))) as nexttime;
If you have only one weekday, you can set all three variables to the same number.
You should be able to formulate the where clause using the DAYNAME(), HOUR(), MINUTE() and SECOND() functions:
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
If performance is inadequate and you start wishing you could index on DAYNAME(columname) for example, you can consider denormalizing your data and storing the DAYNAME value separately.
It might be simpler to switch to Postgres at that point though:
http://www.postgresql.org/docs/9.1/static/indexes-expressional.html