Split data datetime wise in SQL Server - sql

I have a requirement to group the data day-wise from 8:00 AM today to 7:59 AM the next day as 1 full day.
For example from the below table:
SoldDatetime Qty
Dec 20,2015 12:05 AM 1
Dec 20,2015 1:05 AM 2
Dec 20,2015 7:05 AM 3
Dec 20,2015 8:05 AM 4
Dec 20,2015 10:05 AM 5
Dec 20,2015 11:05 PM 6
Dec 21,2015 12:05 AM 7
Dec 21,2015 1:05 AM 8
Dec 21,2015 7:05 AM 9
Dec 21,2015 8:05 AM 10
Dec 21,2015 10:05 AM 11
Dec 21,2015 11:05 PM 12
Dec 22,2015 12:05 AM 13
Dec 22,2015 1:05 AM 14
Dec 22,2015 7:05 AM 15
Dec 22,2015 8:05 AM 16
Dec 22,2015 10:05 AM 17
Dec 22,2015 11:05 PM 18
Dec 23,2015 12:05 AM 19
Dec 23,2015 1:05 AM 20
Dec 23,2015 7:05 AM 21
Dec 23,2015 8:05 AM 22
Dec 23,2015 10:05 AM 23
Dec 23,2015 11:05 PM 24
Dec 24,2015 12:05 AM 25
Dec 24,2015 1:05 AM 26
Dec 24,2015 7:05 AM 27
Dec 24,2015 8:05 AM 28
Dec 24,2015 10:05 AM 29
Dec 24,2015 11:05 PM 30
Dec 25,2015 12:05 AM 31
Dec 25,2015 1:05 AM 32
Dec 25,2015 7:05 AM 33
Dec 25,2015 8:05 AM 34
Dec 25,2015 10:05 AM 35
Dec 25,2015 11:05 PM 36
If I have to run a query to filter for date range Dec 21,2015 8:00 AM to Dec 25,2015 7:59 AM. I need the output in below format
SoldDateRange Qty
Dec 20,2015 8:00 AM - Dec 21,2015 7:59AM 39
Dec 21,2015 8:00 AM - Dec 22,2015 7:59AM 75
Dec 22,2015 8:00 AM - Dec 23,2015 7:59AM 111
Dec 23,2015 8:00 AM - Dec 24,2015 7:59AM 147
Dec 24,2015 8:00 AM - Dec 25,2015 7:59AM 183
Can someone help with the SQL query for this? Thanks in advance

Here is a query which should give you the full output you mentioned in your original question.
SELECT CONCAT(CONVERT(VARCHAR, t.adjustedTime, 107), ' 8:00 AM',
' - ',
CONVERT(VARCHAR, DATEADD(DAY, 1, t.adjustedTime), 107), ' 7:59AM'),
t.Qty
FROM
(
SELECT CAST(DATEADD(HOUR, -8, SoldDateTime) AS DATE) AS adjustedTime, SUM(Qty) AS Qty
FROM yourTable
GROUP BY CAST(DATEADD(HOUR, -8, SoldDateTime) AS DATE)
) t
ORDER BY t.adjustedTime

You can do this by subtracting 8 hours. The basic idea is:
select cast(dateadd(hour, -8, solddaterange) as date) as SoldDate, sum(qty)
from t
group by cast(dateadd(hour, -8, solddaterange) as date)
order by SoldDate;
EDIT:
You could use the same idea. For instance:
where cast(dateadd(hour, -8, solddaterange) as date) = '2016-01-01'

Related

Indexing Time in Redshift

i have a dataset with that has sales by month and a column for when an promotion happens for a number of products.
i want to index the months so that i can compare the different products over a pre and post 12m period easily
this is the data i have
Date
sales.
Promo?
Jan 21
100
Feb 21
110.
Mar 21
100.
apr 21
110.
may 21
90.
jun 21
100.
jul 21
120.
aug 21
140.
X
sep 21
100.
oct 21
90.
nov 21
100.
dec 21
120.
jan 22
110.
feb 22
100
this is what i want
can someone tell me how to do this in redshift?
Date
sales.
Promo?
month index
Jan 21
100
-7.
Feb 21
110.
-6
Mar 21
100.
-5
apr 21
110.
-4
may 21
90.
-3
jun 21
100.
-2
jul 21
120.
-1
aug 21
140.
X
0
sep 21
100.
1
oct 21
90.
2
nov 21
100.
3
dec 21
120.
4
jan 22
110.
5
feb 22
100
6

how to wite the date fuctionality for below output

I want the output like this for whole year:
Jan 01 - Jan 14 - 2021
Jan 15 - Jan 28 - 2021
Jan 29 - Feb 11 - 2021
Feb 12 - Feb 25 - 2021
Feb 26 - Mar 11 - 2021
Mar 12 - Mar 25 - 2021
Mar 26 - Apr 08 - 2021
Apr 09 - Apr 22 - 2021
Apr 22 - May 06 - 2021
May 07 - May 20 - 2021
May 21 - Jun 03 - 2021
Jun 04 - Jun 17 - 2021
Jun 18 - Jul 01 - 2021
Jul 02 - Jul 15 - 2021
Jul 16 - Jul 29 - 2021
Jul 30 - Aug 12 - 2021
Aug 13 - Aug 26 - 2021
Aug 27 - Sep 09 - 2021
Sep 10 - Sep 23 - 2021
Sep 24 - Oct 07 - 2021
Oct 08 - Oct 21 - 2021
Oct 22 - Nov 04 - 2021
Nov 05 - Nov 18 - 2021
Dec 19 - Dec 02 - 2021
Dec 03 - Dec 16 - 2021
Dec 17 - Dec 30 - 2021
One option uses generate_series():
select d.dt dt_start, d.dt + '13 days'::interval dt_end
from generate_series(
date_trunc('year', current_date),
date_trunc('year', current_date) + '1 year'::interval - '13 days'::interval,
'14 days'::interval
) d(dt)
order by dt_start
SELECT to_char(d, 'Mon DD - ')
|| to_char(d + INTERVAL '13 days', 'Mon DD - YYYY')
FROM generate_series(
TIMESTAMP '2021-01-01',
TIMESTAMP '2021-12-17',
INTERVAL '14 days'
) AS d;
?column?
------------------------
Jan 01 - Jan 14 - 2021
Jan 15 - Jan 28 - 2021
Jan 29 - Feb 11 - 2021
Feb 12 - Feb 25 - 2021
Feb 26 - Mar 11 - 2021
Mar 12 - Mar 25 - 2021
Mar 26 - Apr 08 - 2021
Apr 09 - Apr 22 - 2021
Apr 23 - May 06 - 2021
May 07 - May 20 - 2021
May 21 - Jun 03 - 2021
Jun 04 - Jun 17 - 2021
Jun 18 - Jul 01 - 2021
Jul 02 - Jul 15 - 2021
Jul 16 - Jul 29 - 2021
Jul 30 - Aug 12 - 2021
Aug 13 - Aug 26 - 2021
Aug 27 - Sep 09 - 2021
Sep 10 - Sep 23 - 2021
Sep 24 - Oct 07 - 2021
Oct 08 - Oct 21 - 2021
Oct 22 - Nov 04 - 2021
Nov 05 - Nov 18 - 2021
Nov 19 - Dec 02 - 2021
Dec 03 - Dec 16 - 2021
Dec 17 - Dec 30 - 2021
(26 rows)

Add a day to a predefined date SQL Server 2008 R2

My question is very simple, I am making a query which I intend to make an insertion from two dates to a temp Table.
That is, 2020-04-01 00:00:00 and 20-04-01 23:59:00, hence the number of days you need increases.
I am doing it this way E.G:
DECLARE #StartDate DATETIME = '2020-04-01'
DECLARE #EndDate DATETIME = '2020-04-01'
SET #StartDate = #StartDate + '00:00:00'
SET #EndDate = #EndDate + '23:59:00'
WHILE (#StartDate <= #EndDate)
BEGIN
--Insert into a temp table
set #StartDate = DATEADD(DAY, 1, #StartDate);
set #EndDate = DATEADD(day, 1, #EndDate);
print #StartDate
print #EndDate
END;
, however it goes into a repetitive cycle and does not stop. Besides, it is not only respecting the increment of the day that I need.
Can someone help me with this please.
I want to get to this:
Initial date: 2020-04-01 00:00:00.
End Date: 2020-04-01 23:59:00.
Starting day increment 2020-04-02 00:00:00
End Date Increment: 2020-04-02 23:59:00.
My query is throwing this at me:
Apr 2 2020 12:00AM
Apr 2 2020 11:59PM
Apr 3 2020 12:00AM
Apr 3 2020 11:59PM
Apr 4 2020 12:00AM
Apr 4 2020 11:59PM
Apr 5 2020 12:00AM
Apr 5 2020 11:59PM
Apr 6 2020 12:00AM
Apr 6 2020 11:59PM
Apr 7 2020 12:00AM
Apr 7 2020 11:59PM
Apr 8 2020 12:00AM
Apr 8 2020 11:59PM
Apr 9 2020 12:00AM
Apr 9 2020 11:59PM
Apr 10 2020 12:00AM
Apr 10 2020 11:59PM
Apr 11 2020 12:00AM
Apr 11 2020 11:59PM
Apr 12 2020 12:00AM
Apr 12 2020 11:59PM
Apr 13 2020 12:00AM
Apr 13 2020 11:59PM
Apr 14 2020 12:00AM
Apr 14 2020 11:59PM
Apr 15 2020 12:00AM
Apr 15 2020 11:59PM
Apr 16 2020 12:00AM
Apr 16 2020 11:59PM
Apr 17 2020 12:00AM
Apr 17 2020 11:59PM
Apr 18 2020 12:00AM
Apr 18 2020 11:59PM
Apr 19 2020 12:00AM
Apr 19 2020 11:59PM
Apr 20 2020 12:00AM
Apr 20 2020 11:59PM
Apr 21 2020 12:00AM
Apr 21 2020 11:59PM
Apr 22 2020 12:00AM
Apr 22 2020 11:59PM
Apr 23 2020 12:00AM
Apr 23 2020 11:59PM
Apr 24 2020 12:00AM
Apr 24 2020 11:59PM
Apr 25 2020 12:00AM
Apr 25 2020 11:59PM
Apr 26 2020 12:00AM
Apr 26 2020 11:59PM
Apr 27 2020 12:00AM
Apr 27 2020 11:59PM
Apr 28 2020 12:00AM
Apr 28 2020 11:59PM
Apr 29 2020 12:00AM
Apr 29 2020 11:59PM
Apr 30 2020 12:00AM
Apr 30 2020 11:59PM
May 1 2020 12:00AM
May 1 2020 11:59PM
May 2 2020 12:00AM
May 2 2020 11:59PM
May 3 2020 12:00AM
May 3 2020 11:59PM
May 4 2020 12:00AM
May 4 2020 11:59PM
May 5 2020 12:00AM
May 5 2020 11:59PM
May 6 2020 12:00AM
May 6 2020 11:59PM
May 7 2020 12:00AM
May 7 2020 11:59PM
May 8 2020 12:00AM
May 8 2020 11:59PM
May 9 2020 12:00AM
May 9 2020 11:59PM
May 10 2020 12:00AM
May 10 2020 11:59PM
May 11 2020 12:00AM
May 11 2020 11:59PM
May 12 2020 12:00AM
May 12 2020 11:59PM
May 13 2020 12:00AM
May 13 2020 11:59PM
May 14 2020 12:00AM
May 14 2020 11:59PM
May 15 2020 12:00AM
May 15 2020 11:59PM
May 16 2020 12:00AM
May 16 2020 11:59PM
May 17 2020 12:00AM
May 17 2020 11:59PM
May 18 2020 12:00AM
May 18 2020 11:59PM
May 19 2020 12:00AM
May 19 2020 11:59PM
May 20 2020 12:00AM
May 20 2020 11:59PM
May 21 2020 12:00AM
May 21 2020 11:59PM
May 22 2020 12:00AM
May 22 2020 11:59PM
May 23 2020 12:00AM
May 23 2020 11:59PM
May 24 2020 12:00AM
May 24 2020 11:59PM
May 25 2020 12:00AM
May 25 2020 11:59PM
May 26 2020 12:00AM
May 26 2020 11:59PM
May 27 2020 12:00AM
May 27 2020 11:59PM
May 28 2020 12:00AM
May 28 2020 11:59PM
May 29 2020 12:00AM
May 29 2020 11:59PM
May 30 2020 12:00AM
May 30 2020 11:59PM
May 31 2020 12:00AM
May 31 2020 11:59PM
Jun 1 2020 12:00AM
Jun 1 2020 11:59PM
Jun 2 2020 12:00AM
Jun 2 2020 11:59PM
Jun 3 2020 12:00AM
Jun 3 2020 11:59PM
Jun 4 2020 12:00AM
Jun 4 2020 11:59PM
Jun 5 2020 12:00AM
Jun 5 2020 11:59PM
Jun 6 2020 12:00AM
Jun 6 2020 11:59PM
Jun 7 2020 12:00AM
Any suggestion?
Where is my mistake ?.
Thank you.
Use a recursive CTE:
DECLARE #StartDate DATETIME = '2020-04-01';
DECLARE #EndDate DATETIME = '2020-04-01';
with dates as (
select #startdate as startdate, dateadd(minute, -1, dateadd(day, 1, #startdate)) as enddate
union all
select dateadd(day, 1, startdate), dateadd(day, 1, enddate)
from dates
where startdate < #enddate
)
select *
from dates
option (maxrecursion 0);
Here is a db<>fiddle.

How to get the data in decline pattern/trending using Oracle SQL?

How can I get the result only for those monthly data in decline pattern/trending ?
And the data as below;
ID JAN FEB MAR APR MAY JUN
112 50 45 40 35 30 20
113 30 30 30 30 30 30
114 20 25 20 20 20 20
115 45 50 60 60 30 30
Expected output ;
ID JAN FEB MAR APR MAY JUN
112 50 45 40 35 30 20
115 45 50 60 60 30 30
Thanks !
SELECT *
FROM your_table
WHERE JAN > JUN
or
SELECT *
FROM your_table
WHERE JAN > FEB
AND FEB > MAR
AND MAR > APR
AND APR > MAY
AND MAY > JUN
It appears that what you're looking for is
SELECT *
FROM SOME_TABLE
WHERE JAN > FEB OR
FEB > MAR OR
MAR > APR OR
APR > MAY OR
MAY > JUN
Best of luck.

T-SQL - Rolling 12 Month Average

I would like to return rolling 12 month averages for each month in a resulting dataset but am not sure how I can do this.
I thought the following script would work:
DECLARE #StartDate as datetime
DECLARE #EndDate as datetime
SET #StartDate = '01/04/2011'
SET #EndDate = getdate()
select x.FinYear, x.FinMonth, x.MonthText, avg(TimeSeconds) [AverageTimeSeconds]
from times x
where (x.TimeOfCall >= #StartDate and x.TimeOfCall < #EndDate)
group by x.FinYear, x.FinMonth, x.MonthText
order by x.FinYear, x.FinMonth
but it only returns the monthly averages, how do I get the 12 month average leading up to each of the months between the start and end date.
The resulting dataset I am looking for is as follows:
Fin Year Fin Month Month Text Avg Time Seconds R12M Avg Seconds
2015/16 01 Apr 100 101
2015/16 02 May 95 98
2015/16 03 Jun 103 100
2015/16 04 Jul 110 100
2015/16 05 Aug 100 100
2015/16 06 Sep 90 97
2015/16 07 Oct 93 97
2015/16 08 Nov 98 100
2015/16 09 Dec 80 98
2015/16 10 Jan 88 98
2015/16 11 Feb 100 98
2016/17 12 Mar 115 100
2016/17 01 Apr 105 100
2016/17 02 May 98 100
2016/17 03 Jun 95 98
2016/17 04 Jul 102 98
2016/17 05 Aug 109 99
2016/17 06 Sep 104 100
2016/17 07 Oct 98 98
2016/17 08 Nov 99 97
2016/17 09 Dec 90 97
the rolling 12 month average is not an average of the monthly averages but an average of the 12 months leading up to the month in question. So January 2017 would be the average of 01 February 2016 - 31 January 2017 and October 2016 would be 01 November 2015 to 31 October 2016.
I hope you can help :-) .
If you have data for every month, then the following calculates the average over the preceding 12 months (note this is the overall average, not the average of the monthly averages):
select x.FinYear, x.FinMonth, x.MonthText, avg(TimeSeconds)as [AverageTimeSeconds],
(sum(sum(TimeSeconds)) over (order by x.FinYear, x.FinMonth rows between 11 preceding and current row) /
sum(count(*)) over (order by x.FinYear, x.FinMonth rows between 11 preceding and current row)
) as avg_12month
from times x
where x.TimeOfCall >= #StartDate and x.TimeOfCall < #EndDate
group by x.FinYear, x.FinMonth, x.MonthText
order by x.FinYear, x.FinMonth;
Note: The where clause affects the 12-month look-back period. In other worse, the look-back will not include months before this period.