T-SQL go through Dates - sql

I have the following table:
Column1 Column2 Column3
04/07/2019 1
04/08/2019 2
04/09/2019 8
04/10/2019 9
04/11/2019 15
04/12/2019 16
04/13/2019 5
04/14/2019 6
04/15/2019 8
04/16/2019 9
04/17/2019 10
04/18/2019 11
04/19/2019 5
04/20/2019 5
04/21/2019 8
04/22/2019 8
04/23/2019 9
04/24/2019 10
04/25/2019 11
04/26/2019 12
04/27/2019 10
I need to find out a way to iterate through the values in column one and identify weeks which should start from Saturday - Sunday. So, in this example one iteration should be from the 14 - 20th. Or another iteration would be from the 7th through the 13th which is Saturday - Sunday. Then After identifying each week, I need to do some calculation on the other columns.The calculation would be updating Column3 if the total amount for Column2 within 1 week (Based on Column1 Saturday to Sunday) exceeds 40 or not. Then the same for the next iteration of week (Saturday - Sunday).
Desired Results:
Column1 Column2 Column3
04/07/2019 1 56
04/08/2019 2 56
04/09/2019 8 56
04/10/2019 9 56
04/11/2019 15 56
04/12/2019 16 56
04/13/2019 5 56
04/14/2019 6 54
04/15/2019 8 54
04/16/2019 9 54
04/17/2019 10 54
04/18/2019 11 54
04/19/2019 5 54
04/20/2019 5 54
04/21/2019 8 68
04/22/2019 8 68
04/23/2019 9 68
04/24/2019 10 68
04/25/2019 11 68
04/26/2019 12 68
04/27/2019 10 68
Please note: The data can range from 3 weeks to a few month. So, the code needs to capture the weeks for any specific range.

You can use datepart() to get the week of a date. You can then use the week to partition by in a windowed sum(). From there you can UPDATE the table joining a derived table that gets the sum like mentioned before. To make sure the week begins on Sunday issue a SET DATEFIRST 7 before the UPDATE.
SET DATEFIRST 7;
UPDATE t1
SET t1.column3 = t3.column3
FROM elbat t1
INNER JOIN (SELECT t2.column1,
sum(t2.column2) OVER (PARTITION BY datepart(week, t2.column1)) column3
FROM elbat t2) t3
ON t3.column1 = t1.column1;
db<>fiddle

Related

Display rows where multiple columns are different

I have data that looks like this. Thousands of rows returned, but this is just a sample.
Most days have the same numbers in them, but some do not. Note that ID 1 and 5 have identical numbers every day.
ID
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
1
26
26
26
26
26
26
26
2
44
44
30
30
44
44
44
3
55
55
55
55
80
90
55
4
12
12
43
43
43
43
43
5
36
36
36
36
36
36
36
I'd like to only return rows where the days of the week have different numbers.
In this case, the only IDs returned should be 2, 3 & 4.
What would I want this query to look like?
Thanks!
One idea that should work in most RDBMS (with some syntax tweaks) is the following.
This is SQL Server compatible: pivot the days into rows and count the distinct values and filter accordingly:
select id
from t
cross apply (
select Count(distinct d) from (
values(sunday),(monday),(tuesday),(wednesday),(thursday),(friday),(saturday)
)d(d)
)d(v)
where d.v>1

sql sum with separate column for each day

My current code looks like this:
declare #start datetime
declare #end datetime
set #start = '2/16/2020'
set #end = '2/19/2020'
select
s.location, s.department, s.position, SUM(s.hours)/60
from SCHEDULES s where SCHDATE between #start and #end
group by s.location, s.department, s.position
It yields the following results (which is correct):
loc dep pos hrs
2 2 7 96
3 2 11 96
2 2 13 192
3 2 5 96
3 1 4 228
How do I break this out by day so that the format looks like below:
'start' is the #start variable and 'start+1' is simply that plus 1 day, etc.
loc dep pos start start+1 start+2 start+3
2 2 7 24 24 24 24
3 2 11 24 24 24 24
2 2 13 48 48 48 48
3 2 5 24 24 24 24
3 1 4 57 57 57 57
thanks
Sounds like you want to do a pivot:
SELECT *
FROM SCHEDULES s
PIVOT(
SUM(hours)
FOR SCHDATE IN (
[2020-2-16],
[2020-2-17],
[2020-2-18],
[2020-2-19])
) AS pivot_table;
Hopefully the dates you want to work with are fixed and known. If you need to pivot on calculated columns, things seem to get a lot more complicated. For example, see this thread.

Aggregate result from query by quarter SQL

Lets say I have a table which holds all exports for some time back in Microsoft SQL database:
Name:
ExportTable
Columns:
id - numeric(18)
exportdate - datetime
In order to get the number of exports per week I can run the following query:
SELECT DATEPART(ISO_WEEK,[exportdate]) as 'exportdate', count(exportdate) as 'totalExports'
FROM [ExportTable]
Group By DATEPART(ISO_WEEK,[exportdate])
order by exportdate;
Returns:
exportdate totalExports
---------- ------------
27 13
28 12
29 15
30 8
31 17
32 10
33 7
34 15
35 4
36 18
37 10
38 14
39 14
40 21
41 19
Would it be possible to aggregate the week results by quarter so the output becomes something like the bellow?
UPDATE
Sorry for not being crystal clear, I would like the current result to add upp with previous result up to a new quarter.
Note week 41 contains 21+19 = 40
Week 39 contains 157 (13+12+15+8+17+10+7+15+4+18+10+14+14)
exportdate totalExports Quarter
---------- ------------ -------
27 13 3
28 25 3
29 40 3
30 48 3
31 65 3
32 75 3
33 82 3
34 97 3
35 101 3
36 119 3
37 129 3
38 143 3
39 157 3 -- Sum of 3 Quarter values.
40 21 4 -- New Quarter show current week value
41 40 4 -- (21+19)
You can use this.
SELECT
DATEPART(ISO_WEEK,[exportdate]) as 'exportdate'
, SUM( count(exportdate) ) OVER ( PARTITION BY DATEPART(QUARTER,MIN([exportdate])) ORDER BY DATEPART(ISO_WEEK,[exportdate]) ROWS UNBOUNDED PRECEDING ) as 'totalExports'
, DATEPART(QUARTER,MIN([exportdate])) [Quarter]
FROM [ExportTable]
Group By DATEPART(ISO_WEEK,[exportdate])
order by exportdate;
You could use a case statement to separate the dates into quarters.
e.g.
CASE
WHEN EXPORT_DATE BETWEEN '1' AND '4' THEN 1
WHEN Export_Date BETWEEN '5' and '9' THEN 2
ELSE 0 AS [Quarter]
END
Its just an example but you get the idea.
You could then use the alias from the case
SELECT DATEPART(ISO_WEEK,[exportdate]) as 'exportdate', count(exportdate) as 'totalExports', DATEPART(quarter,[exportdate]) as quarter FROM [ExportTable] Group By DATEPART(ISO_WEEK,[exportdate]), DATEPART(quarter,[exportdate]) order by exportdate;

Usage compared to last year

I have a table that contains two columns - date an amount (usage). I want to compare my usage with last year's
Data
Date Amount
01-01-2015 23
02-01-2015 24
03-01-2015 19
04-01-2015 11
05-01-2015 5
06-01-2015 23
07-01-2015 21
08-01-2015 6
09-01-2015 26
10-01-2015 9
[...]
01-01-2016 30
02-01-2016 19
03-01-2016 5
04-01-2016 8
05-01-2016 15
06-01-2016 27
07-01-2016 19
08-01-2016 21
09-01-2016 24
10-01-2016 27
[until today's date]
The sql statement should return results up to today's date and the diff should be a running total - the amount on a day in 2016 minus the amount on the same day in 2015, plus the previous difference. Assuming today is Jan 10, the result would be:
Day Diff
01-01-2016 7 (30-23)
02-01-2016 2 (19-24+7)
03-01-2016 -12 (5-19+2)
04-01-2016 -15 (8-11-12)
05-01-2016 -5 (and so on...)
06-01-2016 -1
07-01-2016 -3
08-01-2016 12
09-01-2016 10
10-01-2016 28
I can't figure out to do this when the data is all in one table...
Thanks
Try this
SELECT t1.date Day,SUM(t2.Diff) FROM
amounts t1
INNER JOIN
(SELECT amounts.date Day, amounts.amount-prevamounts.amount Diff
FROM amounts inner join amounts prevamounts
ON amounts.date=date(prevamounts.date,'+1 years')) t2
ON t2.Day<=t1.date
group by t1.date;
demo here :
http://sqlfiddle.com/#!7/9bd4c/41

How to verify whether records exist for the last x days (calendar days) in SQL not using the between key word

Want verify whether my table is having the records for the last 6 consecutive days in SQL
SNO FLIGHT_DATE LANDINGS
45 9/1/2013 1
31 10/1/2013 1
32 11/1/2013 1
30 11/24/2013 1
27 11/25/2013 1
28 11/26/2013 1
29 11/26/2013 1
33 11/26/2013 1
26 11/30/2013 1
25 12/1/2013 1
34 12/1/2013 1
24 12/2/2013 1
35 12/3/2013 1
36 12/3/2013 1
44 12/4/2013 1
46 12/6/2013 1
47 12/6/2013 1
Is this what you want?
SELECT
*
FROM
Table1
WHERE
FLIGHT_DATE > dateadd(day,-6,datediff(day,0,getdate()))
AND
FLIGHT_DATE < GETDATE();
SQL FIDDLE