SSRS Top N for Dates - sql-server-2008

So I am currently writing an SSRS report which I want to calculate lead time based on an arbitrary number deliveries.
I have my query in SSRS but now I would like to filter it to show the last 5 deliveries. Usually I would use a Top N for filtering but SSRS rightly complains that the number 5 is not a date.
How do you filter the last five latest dates without knowing the exact dates of the records you are returning?
Dataset is as follows (lead time is a calculation of order date less delivery date)
Order | Del_Date | Lead_Time
------|------------|-----------
00001 | 2015-05-01 | 20
00002 | 2015-01-08 | 21
00003 | 2015-02-05 | 22
00004 | 2015-03-11 | 26
00005 | 2015-01-21 | 8
00006 | 2015-04-12 | 12
00007 | 2015-03-02 | 12
00008 | 2015-02-01 | 12
The query should return
Order | Del_Date | Lead_Time
------|------------|-----------
00001 | 2015-05-01 | 20
00003 | 2015-02-05 | 22
00004 | 2015-03-11 | 26
00006 | 2015-04-12 | 12
00007 | 2015-03-02 | 12
Thanks,

Can you try this:
SELECT TOP 5
Order,
Del_Date,
Lead_Time
FROM
[TABLE]
...
ORDER BY
Del_Date DESC

You can modify the data set definition as Matteo suggested or apply a filter to the object displaying the data. Based on your question I am assuming you want to use the object displaying the data to filter your results.
To get the top 5 dates change the data object sorting to the date field and order "Z to A". Then under filters select the date field you want in the expression box. Set the operator to "Top N" and set the value to "=5".

If tablix filter complains about top 5, then you can bring row_number (ranking) to tablix and filter it by ranking <=5

Related

Multiple DateTime range MySql

I have a table
---------+-----------+------------------+--------------------+
| id | user_id | start_date_time | end_date_time |
+---------+---------+-------------------+--------------------+
| 1 | 11 |2019-11-17 20:10:00|2019-11-17 21:05:00 |
| 2 | 11 |2019-11-17 20:18:00|2019-11-17 20:35:00 |
| 3 | 11 |2019-11-17 20:32:00|2019-11-17 21:18:00 |
| 4 | 11 |2019-11-17 20:40:00|2019-11-17 20:50:00 |
| 5 | 11 |2019-11-17 20:45:00|2019-11-17 21:20:00 |
| | | | |
+---------+---------+-------------------+--------------------+
Scenario 1 - If i query for all greater than '2019-11-17 20:18:00' I need to get all records.
Scenario 2 - If i query for all possible dates greater or equals '2019-11-17 21:18:00' It should return record 3 and 5.
For any given time it should look for Start_date_time and End_date_time where given time should be considered as start time and it should look for appropriate end_date_time and output the result.
In a nut shell input time should be taken as starting range and it should look for End_date_time and give me all values between.
How can i accomplish this?
i tried the following ways on db-fiddle https://www.db-fiddle.com/f/bPk1CYioL6cVasStZKzQ4j/7
if i query all records from a given time eg(2019-11-17 20:18:00) the input should be taken as a start datetime of range and look for the most greatest end_date_time and give me the records between them. Example 2019-11-17 20:18:00 this input takes range between input as val1 of range 2019-11-17 20:18:00 to 2019-11-17 21:20:00 the highest end date and give me all records between. And if i query with input 2019-11-17 21:05:00 this should take start range val1 as 2019-11-17 21:05:00 and 2019-11-17 21:20:00 output 1,3,5 records.
The requirement (with the results that you expect) is as simple as that:
select *
from times
where ? <= end_date_time
Replace ? with the datetime that you want to query.
See the demo.

Properly SQL query

I need to skip results with high price per day. I've got a table like this:
+------+-------------+-------+
| days | return_date | value |
+------+-------------+-------+
| 2 | 2017-12-27 | 15180 |
| 3 | 2017-12-28 | 14449 |
| 4 | 2017-12-29 | 13081 |
| 5 | 2017-12-30 | 11203 |
| 6 | 2017-12-31 | 9497 |
| 6 | 2017-12-31 | 9442 |
+------+-------------+-------+
How can I print only the lowest price for 6 days (9442 in this example).
We can use a GROUP BY clause and an aggregate function. For example:
SELECT t.days
, t.return_date
, MIN(t.value) AS min_value
FROM mytable t
GROUP
BY t.days
, t.return_date
This doesn't really "skip" rows. It accesses all the rows that satisfy the conditions in the WHERE clause (in this example, every row in the table). Then MySQL collapses rows into groups (in this example, rows with identical values of days and return_date get put into a group. The MIN(t.value) aggregate function selects out the minimum (lowest) value out of the group.
The query above is just an example of one approach of satisfying a particular specification.

Group by adjacent time values

I hope someone can help with that tricky question:
How can I "GROUP BY" some rows which have a configurable adjacent distance between the timestamps?
Example table:
ID | Value | When
1 | 5 | 2017-06-30 11:45:55
2 | 9 | 2017-06-30 11:45:56
3 | 0 | 2017-06-30 11:45:59
4 | 2 | 2017-06-30 11:46:02
5 | 7 | 2017-06-30 17:19:22
6 | 7 | 2017-06-30 17:19:22
7 | 3 | 2017-06-30 17:19:22
8 | 6 | 2017-06-30 17:19:22
Desired result:
ID | Value | When
3 | 0 | 2017-06-30 11:45:59
7 | 3 | 2017-06-30 17:19:22
The result shall find adjacent entries (in the example two groups of four rows each) and tell the lowest "Value".
Adjacent distance can be any value like one minute or ten minutes.
I tried to reformat the date to be able to "GROUP BY" without seconds but this won't work for the first result.
My MySQL programming skills are limited but it could be done with following steps:
SELECT and ORDER BY "When"
Go though values and tell difference between current and previous "When" value, if within range, then GROUP, if not output a new row.
Any idea?
Finally I decided to write a C program which uses a view in the DB to obtain raw sorted data. The program then outputs groups if the difference between the timestamps is within the desired limit.
The output is then put back into the database.

SQL - select x entries within a timespan

I'm creating a database (in MySQL) with a table of measurements. For each measurement I want to store the DateTime it came in. For showing plots within an app for different intervals (measurements of the day/week/month/year) I want sample the data points I have, so I can return e. g. 30 data points for the whole year as well as for the day/hour. This is the same as done with stock price graphs:
stock price plot for 1 day
vs
stock price plot for 1 month
As you can see, the amount of data points is the same in both pictures.
So how can I select x entries within a timespan in MySQL via SQL?
My data looks like this:
+====+====================+=============+==========+
| id | datetime | temperature | humidity |
+====+====================+=============+==========+
| 1 | 1-15-2016 00:30:00 | 20 | 40 |
+----+--------------------+-------------+----------+
| 2 | 1-15-2016 00:35:00 | 19 | 41 |
+----+--------------------+-------------+----------+
| 3 | 1-15-2016 00:40:00 | 20 | 40 |
+----+--------------------+-------------+----------+
| 4 | 1-15-2016 00:45:00 | 20 | 42 |
+----+--------------------+-------------+----------+
| 5 | 1-15-2016 00:50:00 | 21 | 42 |
+----+--------------------+-------------+----------+
| 6 | 1-15-2016 00:55:00 | 20 | 43 |
+----+--------------------+-------------+----------+
| 7 | 1-15-2016 01:00:00 | 21 | 43 |
+====+====================+=============+==========+
Let's say, I always want two data points (in reality a lot more). So for the last half hour I want the database to return data point 1 and 4, for the last ten minutes I want it to return 6 and 7.
Thanks for helping!
PS: I'm sorry for any errors in my English
OK, assuming a very simple systematic approach, you can get the first and last entry for any defined period:
select *
from table
where mydatetime =
(select
max(mydatetime)
from table
where mydatetime between '2017-03-01' and '2017-03-15'
)
OR mydatetime =
(select
min(mydatetime)
from table
where mydatetime between '2017-03-01' and '2017-03-15'
)
I believe your answer can be found at the following location:
https://stackoverflow.com/a/1891796/7176046
If you are looking to filter out any items not within your date/time your query would use:
Select * from table where Date/Time is (What you want to sort by)

MySQL how to present day results (starting value, total change and day-end value from table

I have this table (have a look on SQLFiddle)
In previous steps the record number has been determined and the values for "PrevVal" and "NewVal" have been calculated.
The record's end value ("NewVal"), becomes the next record's starting value ("PrevVal")
I would like to condense the table in such a way that there is only one record per day, containing:
the date starting value "StartOfDay",
the total change during the day "TotalChange" and
the resulting day-end value "EndOfDay"
The desired result can be seen in the demo table "ChangesPerDayCondensed"
Who can help me solve this (a stored procedure is OK).
Thnx
I am a little confused whey the record numbers are going the opposite way. But neverthless you could solve this by evaluating the starting value and sum of mutations separatately and then adding them all to come up with ending value..
Ordering the results descending as the record number again needs to be lower for a higher date.
insert into ChangesPerDayCondensed
select #recrd:=#recrd+1, a.MyDate, b.PrevVal, a.Mutation, b.PrevVal+a.Mutation
from
(select MyDate, sum(Mutation) as Mutation from MutationsPerDay group by MyDate) a,
(select b.MyDate, b.PrevVal from (select MyDate, max(RecNo) as RecNo from MutationsPerDay group by MyDate) a, MutationsPerDay b where a.RecNo = b.RecNo) b,
(select #recrd:=0) c
where a.MyDate = b.MyDate order by MyDate desc;
I'd do it this way:
First create a lookup for each day (find first and lasts ReqNo) and then join two times to the Daily table and calculate the changes:
SELECT first_.MyDate,
first_.PrevVal AS StartOfDay,
last_.NewVal AS EndOfDay,
(last_.NewVal - first_.PrevVal) AS TotalChange
FROM
(SELECT mpd1.MyDate,
max(mpd1.RecNo) AS first_rec_no,
min(mpd1.RecNo) AS last_rec_no
FROM MutationsPerDay mpd1
GROUP BY MyDate) AS lo
JOIN MutationsPerDay AS first_ ON lo.first_rec_no = first_.RecNo
JOIN MutationsPerDay AS last_ ON lo.last_rec_no = last_.RecNo
Explanation:
What you actually want is:
For every day the first and the last value (and the difference).
So what you need to find first is for every date the id of the first and the last value:
SELECT mpd1.MyDate,
max(mpd1.RecNo) AS first_rec_no,
min(mpd1.RecNo) AS last_rec_no
FROM MutationsPerDay mpd1
GROUP BY MyDate
----------------------------------------------------
| MyDate | first_rec_no | last_rec_no |
----------------------------------------------------
| 2016-12-05 00:00:00 | 16 | 13 |
| 2016-12-07 00:00:00 | 12 | 12 |
| 2016-12-12 00:00:00 | 11 | 8 |
| 2016-12-14 00:00:00 | 7 | 7 |
| 2016-12-20 00:00:00 | 6 | 6 |
| 2016-12-21 00:00:00 | 5 | 4 |
| 2016-12-28 00:00:00 | 3 | 3 |
| 2016-12-29 00:00:00 | 2 | 2 |
| 2016-12-30 00:00:00 | 1 | 1 |
----------------------------------------------------
Then you can use these first and last id's to find the corresponding values in the source table. For example for the 2016-12-21 you'd get the rows with the id's first: 5 and last: 4
The PrevVal record no 5 represents the first value you have seen at this day and NewVal in record no 4 represents the last value you have seen at this day. If you subtract them you'll get the change for this day.
I hope this clarifies the methodology a bit.