How to get the correct date format - snowflake-cloud-data-platform

How to get this date format in Snowflake?
"day; YYYY/MM/DD; HH:MM AM - HH:MM AM" format in snowflake
Tried these logic:
select current_date()
,to_char(DAY() , 'MMMM DD, YYYY')
,to_date (to_char(current_date() , 'MMMM DD, YYYY'), 'MMMM DD, YYYY')
;
select to_timestamp('2019-02-28 23:59:59.000000000 -07:00', 'YYYY-MM-DDHH24:MI:SS.FF TZH:TZM');

You question seems rather confused.
select to_timestamp_tz('2019-02-28 23:59:59.123400000 -07:00', 'YYYY-MM-DDHH24:MI:SS.FF TZH:TZM');
gives:
TO_TIMESTAMP_TZ('2019-02-28 23:59:59.123400000 -07:00', 'YYYY-MM-DDHH24:MI:SS.FF TZH:TZM')
2019-02-28 23:59:59.123 -0700
so it seems possible to parse the string to -> timestamp with timezone.
select
column1 as cd
,to_char(cd, 'MMMM DD, YYYY') as d1
,to_char(cd, 'DY; YYYY/MM/DD; HH:MI AM') as d2
FROM VALUES
(current_date),
(current_timestamp)
gives:
CD
D1
D2
2022-04-07 00:00:00.000 -0700
April 07, 2022
Thu; 2022/04/07; 00:00 AM
2022-04-07 00:39:13.433 -0700
April 07, 2022
Thu; 2022/04/07; 00:39 AM
Full Day:
So as noted in the comments there are a couple ways to get Day of Week:
select
current_date() as cd
,extract ('dayofweek_iso',current_date()) as dow_1
,dayofweekiso(cd) as dow_2
,decode(dow_1, 1, 'Monday', 2, 'Tuesday', 3, 'Wednesday', 4, 'Thursday', 5, 'Friday', 6, 'Saturday', 7, 'Sunday') as full_day;
CD
DOW_1
DOW_2
FULL_DAY
2022-04-07
4
4
Thursday
Full Output:
select
current_timestamp() as cd
,extract ('dayofweek_iso',current_date()) as dow_1
,dayofweekiso(cd) as dow_2
,decode(dow_1, 1, 'Monday', 2, 'Tuesday', 3, 'Wednesday', 4, 'Thursday', 5, 'Friday', 6, 'Saturday', 7, 'Sunday') as full_day
,full_day || to_char(cd, '; YYYY/MM/DD; HH:MI AM - HH:MI AM') as full_format;
gives:
CD
DOW_1
DOW_2
FULL_DAY
FULL_FORMAT
2022-04-07 14:57:11.717 -0700
4
4
Thursday
Thursday; 2022/04/07; 14:57 PM - 14:57 PM

Related

Exapansion of rows based on Calendar

My fact table is following
declare #fact as TABLE (WO varchar(3), startYear int, startFiscalPeriod int, endFiscalPeriod int)
INSERT INTO #fact
Select WO, startYear,startFiscalPeriod, endFiscalPeriod
from
(
VALUES
('WO1', 2020, 202011, 202106),
('WO2', 2020, 202009, 202106),
('WO3', 2021, 202102, 202106)
) t (WO, startYear,startFiscalPeriod, endFiscalPeriod)
select * from #fact
WO
startYear
startFiscalPeriod
endFiscalPeriod
WO1
2020
202011
202106
WO2
2020
202009
202106
WO3
2021
202102
202106
I want to expand the rows based on the interval between startFiscalPeriod and endFiscalPeriod, like following
;with cte as
(select WO, startYear,startFiscalPeriod, endFiscalPeriod from #fact
UNION ALL
select WO, startYear,startFiscalPeriod+1,endFiscalPeriod from CTE
where startFiscalPeriod<[endFiscalPeriod])
However, I want the expansion to happen based on a calendarTable.
declare #Calendar as TABLE (fiscalYear int, periodNumber int, fiscalPeriod int)
INSERT INTO #Calendar
Select fiscalYear, periodNumber,fiscalPeriod
from
(
VALUES
(2020, 1, 202001),
(2020, 2, 202002),
(2020, 3, 202003),
(2020, 4, 202004),
(2020, 5, 202005),
(2020, 6, 202006),
(2020, 7, 202007),
(2020, 8, 202008),
(2020, 9, 202009),
(2020, 10, 202010),
(2020, 11, 202011),
(2020, 12, 202012),
(2021, 1, 202101),
(2021, 2, 202102),
(2021, 3, 202103),
(2021, 4, 202104),
(2021, 5, 202105),
(2021, 6, 202106)
) t (fiscalYear, periodNumber,fiscalPeriod)
My desired output is following which I can't generate by simply expanding the rows on simple do while logic. Is there any way to condition the do while logic based on the calendar?
WO
startYear
startFiscalPeriod
endFiscalPeriod
WO1
2020
202011
202106
WO1
2020
202012
202106
WO1
2020
202101
202106
WO1
2020
202102
202106
WO1
2020
202103
202106
WO1
2020
202104
202106
WO1
2020
202105
202106
WO1
2020
202106
202106
WO2
2020
202009
202106
WO2
2020
202010
202106
WO2
2020
202011
202106
WO2
2020
202012
202106
WO2
2020
202101
202106
WO2
2020
202102
202106
WO2
2020
202103
202106
WO2
2020
202104
202106
WO2
2020
202105
202106
WO2
2020
202106
202106
WO3
2021
202102
202106
WO3
2021
202103
202106
WO3
2021
202104
202106
WO3
2021
202105
202106
WO3
2021
202106
202106
Thank you in advance
Why not join the two tables with a between condition, like Calendar.fiscalPeriod between fact.startFiscalPeriod and fact.endFiscalPeriod?
select
f.WO
, f.startYear
, c.fiscalPeriod startFiscalPeriod
, f.endFiscalPeriod
from
#fact f
inner join #Calendar c on c.fiscalPeriod between f.startFiscalPeriod and f.endFiscalPeriod
order by
f.WO
, c.fiscalPeriod

SQL Server take a time duration and parse the time into the hour parts of that duration

I am posting this question again because the project has changed and the previous answers don't return the desired results. Ambulances and fire trucks have the dispatch time when an emergency occurred and an end time for when the emergency was declared over.
Event 1 starts on May 1, 2021 10:17:33 and ends at may 1, 2021 10:33:41.
Event 2 starts on May 1, 2021 11:50:52 and ends at May 1, 2021 13:18:21.
I would like to parse the amount of time from the start to the end and place it into the hour parts when it occurs. For example; Event 1 starts at 10:17 and ends at 10:33. It would place 16 minutes minutes in the 10:00 hour part for that day. Event 2 would place 10 minutes in the 11:00 hour part, 60 minutes in the 12:00 hour part and 18 minutes in the 13:00 hour part. Place the minutes in the hours during which the event occured.
The results should look the following. Although I am flexible. For example, if the name of the truck cannot be returned in the results that would be ok because if the EventID is there, I could relate back to the original table.
EventID
Ambulance
EventDayOfYear
EventHour
MinutesAllocated
1
Medic10
121
10
16
1
Medic10
121
11
10
2
Ladder73
121
11
10
2
Ladder73
121
12
60
2
Ladder73
121
13
18
3
Engine41
121
13
33
3
Engine41
121
14
21
4
Medic83
121
15
32
4
Medic83
121
16
5
5
Rescue32
121
16
33
6
Medic09
121
23
16
6
Medic09
122
0
39
7
Engine18
121
23
28
7
Engine18
122
0
60
7
Engine18
122
1
34
8
Rescue63
122
0
35
The following SQL code comes close to working to deliver the right result. But it does not overlap days. There are many emergency events that start at 2300 hours and last until 0300 hours the following day.
DECLARE #tempFireEvents TABLE
(
EventID INT NOT NULL
, Apparatus VARCHAR(10) NOT NULL
, StartDateTime DATETIME NOT NULL
, EndDateTime DATETIME NOT NULL
, DurationInSeconds INT NOT NULL
)
INSERT INTO #tempFireEvents
VALUES
(1, 'Medic10', 'may 1, 2021 10:17:33', 'may 1, 2021 10:33:41', 968) /*This event is entirely within 1000 hours*/
, (2, 'Ladder73', 'may 1, 2021 11:50:52', 'may 1, 2021 13:18:21', 5249) /*This event spans 1100, 1200 and 1300 hours*/
, (3, 'Engine41', 'may 1, 2021 13:27:17', 'may 1, 2021 14:21:18', 3241) /*This event overlaps 1300 and 1400 hours*/
, (4, 'Medic83', 'may 1, 2021 15:28:08', 'may 1, 2021 16:05:48', 2260) /*This event overlaps 1500 and 1600 hours*/
, (5, 'Rescue32', 'may 1, 2021 16:20:43', 'may 1, 2021 16:53:28', 1965) /*This event is entirely within the 1600 hour part*/
, (6, 'Medic09', 'may 1, 2021 23:44:06', 'may 2, 2021 00:39:52', 3346) /*Notice this overlaps the 2300 and 0000 hours into the following day*/
, (7, 'Engine18', 'may 1, 2021 23:32:58', 'may 2, 2021 01:34:13', 7275) /*Notice this overlaps the 2300, 0000 and 0100 hours into the following day*/
, (8, 'Rescue63', 'may 2, 2021 00:17:45', 'may 2, 2021 00:52:09', 2064) /*Notice this is the 00 hour of the day and does not show in the results*/
;
WITH AllHours AS
(
SELECT 1 AS hourInt
UNION ALL
SELECT hourInt + 1
FROM AllHours
WHERE hourInt < 23
)
,
Combined AS
(
SELECT
T.EventID
, H.hourInt
, CASE WHEN DATEPART(HOUR, T.StartDateTime) = H.hourInt THEN 1 ELSE 0 END AS isStart
, CASE WHEN DATEPART(HOUR, T.EndDateTime) = H.hourInt THEN 1 ELSE 0 END AS isEnd
, T.StartDateTime
, T.EndDateTime
FROM #tempFireEvents AS [T]
JOIN AllHours AS [H] ON H.hourInt BETWEEN DATEPART(HOUR, T.StartDateTime) AND DATEPART(HOUR,T.EndDateTime)
)
SELECT
EventID
, hourInt
, CASE WHEN isStart = 1 AND isEnd = 0 THEN 60 - DATEPART(MINUTE, StartDateTime)
WHEN isStart = 0 AND isEnd = 1 THEN DATEPART(MINUTE, EndDateTime)
WHEN isStart = 1 AND isEnd = 1 THEN DATEPART(MINUTE, EndDateTime) - DATEPART(MINUTE, StartDateTime)
ELSE 60
END AS MinutesInThisHour
FROM Combined
ORDER BY EventID ASC, hourint ASC
;
I have a suspiction that SQL Server may not be the best method to achieve the goal. It may need to be written in Python with increment and decrement and counters.
If it helps, I have a calendar table that looks like:
May 1, 2021 00:00:00
May 1, 2021 01:00:00
May 1, 2021 02:00:00
May 1, 2021 03:00:00
May 1, 2021 04:00:00
May 1, 2021 05:00:00
May 1, 2021 06:00:00
Would a calendar table be useful in solving this problem?
…
CREATE TABLE tempFireEvents
(
EventID VARCHAR(8) NOT NULL,
StartDateTime DATETIME NOT NULL,
EndDateTime DATETIME NOT NULL
)
INSERT INTO tempFireEvents
VALUES
('fire0001', 'november 1, 2018 10:45:00', 'november 2, 2018 11:30:00'),
('fire0002', 'november 1, 2018 11:50:00', 'november 1, 2018 13:10:00'),
('fire0003', 'november 1, 2018 13:20:00', 'november 1, 2018 14:20:00'),
('fire0004', 'november 1, 2018 15:25:00', 'november 1, 2018 16:05:00'),
('fire0005', 'november 1, 2018 16:20:00', 'november 2, 2018 17:00:00'),
('fire0006', 'november 1, 2018 16:20:00', 'november 1, 2018 17:01:00');
select e.*, hr.ld,
60 - case when e.startdatetime > hr.ld then datepart(minute, e.startdatetime) else 0 end
+ case when e.enddatetime < hr.ud then datepart(minute, e.enddatetime)-60 else 0 end as allocatedminutes
from tempFireEvents as e
cross apply
(
select
dateadd(hour, datepart(hour,e.startdatetime)+t.rn-1, cast(cast(e.startdatetime as date) as datetime)) as ld,
dateadd(hour, datepart(hour,e.startdatetime)+t.rn, cast(cast(e.startdatetime as date) as datetime)) as ud,
rn
from
(
-- a tally, max 100 rows .. max 100 hours duration
select top (1+datediff(hour,e.startdatetime,dateadd(minute, -1, e.enddatetime))) row_number() over(order by ##spid) as rn
from (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) as a(n)
cross join (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) as b(n)
) as t
) as hr;

Obtaining the date of 2 Saturdays ago and Last Friday

How can I obtain the date of 2 Fridays ago and 2 Saturdays ago (SQL Server 2012+)
For example,
if run today, Monday Oct 12, my query should result in Sat Oct 3 and Friday Oct 9
if run on Tuesday Oct 20, my dates should be Sat Sat Oct 10 and Friday Oct 16
I am looking for an answer like select xyz getdate() ....
#Andresbi, your examples states 2 Saturdays before and 1 Friday before.
I think this code gives you the result:
declare #dt datetime = '20201020'
select
(
/* Previous sunday */
#dt - datepart(dw, #dt) + 1
/* Previous saturday */
- 1
/* and the saturday before */
- 7
),
(
/* Previous sunday */
#dt - datepart(dw, #dt) + 1
/* Previous friday */
- 2
)
select dateadd(day, -08, dateadd(wk, datediff(wk, 0, getdate()), 0))
select dateadd(day, -10, dateadd(wk, datediff(wk, 0, getdate()), 0))

Format date to include day of week

I have a SQL Server 2012 query that converts date to VARCHAR
SELECT
CONVERT(VARCHAR(12), dbo.Download.Date_of_Download, 107) as Date_to_Display,
dbo.Download.Number_of_Computers
FROM dbo.Download
ORDER BY dbo.Download.Date_of_Download DESC
Below are results
Date_to_Display Number_of_Computers
-----------------------------------
Aug 14, 2014 240
Aug 13, 2014 519
Aug 12, 2014 622
Aug 11, 2014 2132
Aug 10, 2014 1255
Aug 09, 2014 3240
How do I include day of week, i.e. Saturday, Aug 09, 2014 ?
try this:
select datename(dw,getdate())
output:
------------------------------
Thursday
(1 row(s) affected)
using your query:
SELECT
Datename(dw, dbo.Download.Date_of_Download)+', '+CONVERT(VARCHAR(12), dbo.Download.Date_of_Download, 107) as Date_to_Display,
dbo.Download.Number_of_Computers
FROM dbo.Download
ORDER BY dbo.Download.Date_of_Download DESC
In SQL Server version 2012 and later, there is the FORMAT TSQL function that can do what you want. The "dddd" portion does day of the week:
SELECT
FORMAT(dbo.Download.Date_of_Download, 'dddd MMM dd, yyyy') as Date_to_Display,
dbo.Download.Number_of_Computers
FROM dbo.Download
ORDER BY dbo.Download.Date_of_Download DESC
MS docs: https://learn.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql

DATEDIFF with cutoff time

I'm working on a Room Scheduling application. We have this Room Check Out Rule that we need follow. All
room check out should be 12:00 PM. If the check out date is after 12.00 PM it will be considered additional 1 day.
Below is my T-SQL code that returns 5 days.
SELECT DATEDIFF(day, '3/12/2013 12:00:00 PM', '3/17/2013 3:00:00 PM');
If you see the code above the end date is 3:00:00 PM. How can I tweak this code to return 6 days instead of 5?
What if I have this code?
SELECT CEILING(DATEDIFF(SECOND, '3/12/2013 02:00:00 PM' , '3/17/2013 12:50:36 PM') / (24.0 * 60 * 60))
The above code still returns 5 days instead of 6.
SELECT CEILING(DATEDIFF(SECOND, '3/12/2013 12:00:00 PM', '3/17/2013 12:00:01 PM') / (24.0 * 60 * 60))
The correct way is to subtract 12 hours from StartDate and EndDate, then take a day-diff + 1:
declare #dateStart as datetime, #dateEnd as datetime
set #dateStart = cast('20130301 11:59:59 AM' as datetime)
set #dateEnd = cast('20130301 12:01:01 PM' as datetime)
select
#dateStart,
#dateEnd
select days = 1 + datediff(d,#dateStart,#dateEnd)
select
days = 1 + datediff(d, dateadd(hh, -12, #dateStart), dateadd(hh, -12, #dateEnd))
returns this:
----------------------- -----------------------
2013-03-01 11:59:59.000 2013-03-01 12:01:01.000
days
-----------
1
days
-----------
2
Clearly the second formula is correct, not the first.
Perhaps you can count hours:
SELECT DATEDIFF(hour, '3/12/2013 12:00:00 PM', '3/17/2013 3:00:00 PM');
Therefore, 123 > 120 (or divided by 24 - 5.125 > 5) accounts for 6 days.

Resources