Query to convert UTC to CST - sql

I'm using SQL Server to count rows in a 24 hour period. I've accomplished that, however I can't figure out how to convert the UTC time to CST that the database stores.
Then...
How to breakdown the 24 hours into 24 x 1 hour blocks with a SUM or Count of each hours rows?
Convert UTC TIME to CST?
Query?
-- THEN
Select COUNT (*) AS Total
From readmodels.Database
Where
Timestamp >= '2018-01-18' AND
Timestamp <= '2018-01-19'
-- Then Breakdown the count into 24 - 1 hour blocks

If you only need to convert from UTC to CST. You can simply use DATEADD(hour, -6, Timestamp) in your query.
e.g.
Select COUNT(*) as count, DATEPART(year, DATEADD(hour, -6, Timestamp)) as year, DATEPART(month, DATEADD(hour, -6, Timestamp)) as month, DATEPART(day, DATEADD(hour, -6, Timestamp)) as day, DATEPART(hour, DATEADD(hour, -6, Timestamp)) as hour
From readmodels.Database
Where
DATEADD(hour, -6, Timestamp) >= '2018-01-18' AND
DATEADD(hour, -6, Timestamp) <= '2018-01-19'
Group by DATEPART(year, DATEADD(hour, -6, Timestamp)), DATEPART(month, DATEADD(hour, -6, Timestamp)), DATEPART(day, DATEADD(hour, -6, Timestamp)), DATEPART(hour, DATEADD(hour, -6, Timestamp))

--this is what I ended up using
SELECT dateadd(hour, datediff(hour, 0, TimeStamp), 0) as TimeStampHour_CST, Count(*) As Total_Per_Hour
FROM readmodels.database
WHERE Timestamp >= '2018-01-17' AND
Timestamp <= '2018-01-18'
GROUP BY dateadd(hour, datediff(hour, 0, TimeStamp), 0)
ORDER BY dateadd(hour, datediff(hour, 0, TimeStamp), 0);

Related

Average Counts by Hour by Day of Week

This question helped get me part of the way there:
SELECT
[Day],
[Hour],
[DayN],
AVG(Totals) AS [Avg]
FROM
(
SELECT
w = DATEDIFF(WEEK, 0, ForDateTime),
[Day] = DATENAME(WEEKDAY, ForDateTime),
[DayN] = DATEPART(WEEKDAY, ForDateTime),
[Hour] = DATEPART(HOUR, ForDateTime),
Totals = COUNT(*)
FROM
#Visit
GROUP BY
DATEDIFF(WEEK, 0, ForDateTime),
DATENAME(WEEKDAY, ForDateTime),
DATEPART(WEEKDAY, ForDateTime),
DATEPART(HOUR, ForDateTime)
) AS q
GROUP BY
[Day],
[Hour],
[DayN]
ORDER BY
DayN;
How could this be changed so rather than showing the average by Hour, e.g. 9, 10, 11, 12, etc. It shows it by 09:30-10:30,10:30-11:30,11:30-12:30,12:30-13:30 all the way up to 23:30.
A simple approach is to offset ForDateTime by 30 minutes. Basically you just need to replace every occurence of ForDateTime with dateadd(minute, 30, ForDateTime) in the query.
In the resultset, Hour 9 gives you the timeslot from 8:30 to 9:30, and so on.

Convert DATEDIFF from SQL Server to redshift

I have script for SQL Server that I need to convert to redshift.
Here is part of it, where I have problem with
LEFT JOIN
(SELECT
cog.ClientId,
MAX(CASE me.metrickey WHEN 'contacts-employee_active_count_day_org' THEN mu.value ELSE 0 END) AS ActiveEmployees
FROM
public.module_utilization mu
JOIN
(SELECT
me.id,
me.ChannelId + '-' + me.metrickey AS MetricKey
FROM
public.module_metric me) AS me ON me.id = mu.metricid
LEFT JOIN
public.contacts_client_organization cog ON cog.clientorganizationid = mu.organizationid
WHERE
mu.dy >= DATEADD(Day, -30, GETDATE())
AND me.metrickey IN ('contacts-employee_active_count_day_org')
GROUP BY
cog.clientid) metrics ON metrics.ClientId = be.clientid
WHERE
be.organizationid = 65277
AND be.timeworkedfrom >= DATEADD(MONTH, -6, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
AND be.timeworkedfrom < TO_CHAR(DATE_TRUNC('month', GETDATE()), 'MM/DD/YYYY')
AND be.isdeleted IS NULL
AND be.isvoid IS NULL
At this line
AND be.timeworkedfrom >= DATEADD(MONTH, -6, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
I get this error
Invalid operation: function pg_catalog.date_diff("unknown", integer, timestamp without time zone) does not exist;
As I understood it because of 0
How I can fix this stuff?
Your highlighted WHERE clause logic is comparing timeworkedfrom to a date six months earlier than the first of the current month. You may change this:
AND be.timeworkedfrom >= DATEADD(MONTH, -6, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
to this:
AND be.timeworkedfrom >= date_trunc('month', current_date) - interval '6 month'

How to count the rows

How i can count the rows between the two dates.
SELECT Count(DATEDIFF(day, ReceiptDate,GETDATE()))
As TotalDays
From JobDetails
Where Receiptdate Between DATEADD(day, -30, GETDATE()) and DATEADD(day, -90, GETDATE())
AND RepairCompleted='N'
Group By ReceiptDate
for example i want to check 30 to 90 days not completed jobs count.
Try this:
SELECT Count(*) As TotalDays
FROM JobDetails
WHERE Receiptdate >= DATEADD(day, -90, GETDATE())
AND Receiptdate <= DATEADD(day, -30, GETDATE())
AND RepairCompleted='N'

SQL Server / T-SQL: Selecting a specific interval ( group by )

I want to write a select that aggregates over data (which has a DATETIME column as ID) with ANY interval theoretically possible (like 1hr, 1hr and 22seconds, 1year and 3minutes, etc. ).
This select should be able to aggregate by 1hr, 12min, 14seconds and should return 3 rows
SELECT DATEPART(YEAR,id) as year,
DATEPART(MONTH,id) as month,
DATEPART(DAY,id) as day,
DATEPART(HOUR,id) as hour,
DATEPART(MINUTE,id) as minute,
AVG([Open]),
AVG([Close]),
AVG([Min]),
AVG([Max])
FROM QuoteHistory
where id between '2000-02-06 17:00:00.000' and '2000-02-06 20:36:42.000'
GROUP BY
DATEPART(YEAR,id),
DATEPART(MONTH,id),
DATEPART(DAY,id),
DATEPART(HOUR,id),
DATEPART(MINUTE,id)
ORDER BY 1,2,3,4,5;
I am kind of stuck here and can't get my head around this problem.. For "simple intervals" like "30 minutes" i could just add a modulo
DATEPART(MINUTE,id)%2
but when the interval "touches" more than 1 part of the date, I'm stuck.
Any help appreciated, thx!
Assuming some parameters here:
;WITH Date_Ranges AS (
SELECT
#min_datetime AS start_datetime,
DATEADD(SECOND, #seconds,
DATEADD(MINUTE, #minutes,
DATEADD(HOUR, #hours,
DATEADD(DAY, #days,
DATEADD(WEEK, #weeks,
DATEADD(MONTH, #months,
DATEADD(YEAR, #years, #min_datetime))))))) AS end_datetime
UNION ALL
SELECT
DATEADD(SECOND, 1, end_datetime),
DATEADD(SECOND, #seconds,
DATEADD(MINUTE, #minutes,
DATEADD(HOUR, #hours,
DATEADD(DAY, #days,
DATEADD(WEEK, #weeks,
DATEADD(MONTH, #months,
DATEADD(YEAR, #years, end_datetime)))))))
FROM
Date_Ranges
WHERE
DATEADD(SECOND, 1, end_datetime) < #max_datetime
)
SELECT
DR.min_datetime,
DR.max_datetime,
AVG([Open]),
AVG([Close]),
AVG([Min]),
AVG([Max])
FROM
Date_Ranges DR
LEFT OUTER JOIN Quote_History QH ON
QH.id BETWEEN DR.min_datetime AND DR.max_datetime
GROUP BY
DR.min_datetime,
DR.max_datetime
ORDER BY
DR.min_datetime,
DR.max_datetime
You might need to fiddle with how to handle the edge cases (that 1 second range between date ranges could be a problem depending on your data). This should hopefully point you in the right direction though.

SQL: Daily Average of Logins Per Hour

This query is producing counts of logins per hour:
SELECT DATEADD(hour, DATEDIFF(hour, 0, EVENT_DATETIME), 0),
COUNT(*)
FROM EVENTS_ALL_RPT_V1
WHERE EVENT_NAME = 'Login'
AND EVENT_DATETIME >= CONVERT(DATETIME, '2010-03-17 00:00:00', 120)
AND EVENT_DATETIME <= CONVERT(DATETIME, '2010-03-24 00:00:00', 120)
GROUP BY DATEADD(hour, DATEDIFF(hour, 0, EVENT_DATETIME), 0)
ORDER BY DATEADD(hour, DATEDIFF(hour, 0, EVENT_DATETIME), 0)
...with lots of results like this:
Datetime COUNT(*)
----------------------------------
2010-03-17 12:00:00.000 135
2010-03-17 13:00:00.000 129
2010-03-17 14:00:00.000 147
What I need to figure out is how to query the average logins per hour for a given day. Any help?
Use the AVG aggregate function:
SELECT CONCAT(DATE_FORMAT(t.event_datetime, '%Y-%m-%d %H'), ':00:00.000') AS hr,
COUNT(*) AS cnt,
AVG(*) AS avg
FROM EVENTS_ALL_RPT_V1 t
WHERE t.event_name = 'Login'
AND t.event_datetime BETWEEN '2010-03-24' AND '2010-03-17'
GROUP BY CONCAT(DATE_FORMAT(t.event_datetime, '%Y-%m-%d %H'), ':00:00.000')
ORDER BY hr
The ORDER BY clause can use column aliases, but GROUP BY can not.
SELECT AVG(m.countLogin) FROM
(SELECT DATEADD(hour, DATEDIFF(hour, 0, EVENT_DATETIME), 0),
COUNT(*) as countLogin
FROM EVENTS_ALL_RPT_V1
WHERE EVENT_NAME = 'Login'
AND EVENT_DATETIME >= CONVERT(DATETIME, '2010-03-17 00:00:00', 120)
AND EVENT_DATETIME <= CONVERT(DATETIME, '2010-03-24 00:00:00', 120)
GROUP BY DATEADD(hour, DATEDIFF(hour, 0, EVENT_DATETIME), 0)
ORDER BY DATEADD(hour, DATEDIFF(hour, 0, EVENT_DATETIME), 0)) m
Note : Don't forget to give alias for new outer table.
You can do something like this
SELECT AVG(cnt) FROM (
your other query
)
But you need to name the second column cnt and maybe add a where clause that only looks at the given date.
This will select all the logins on the 18th of March per hour and then calculates the average.
SELECT AVG(count) FROM
(
SELECT COUNT(*) count
FROM EVENTS_ALL_RPT_V1
WHERE EVENT_NAME = 'Login' AND
EVENT_DATETIME >= CONVERT(DATETIME,'2010-03-18 00:00:00', 120) AND
EVENT_DATETIME <= CONVERT(DATETIME,'2010-03-19 00:00:00', 120)
GROUP BY DATEADD(hour, DATEDIFF(hour, 0, EVENT_DATETIME), 0)
ORDER BY DATEADD(hour, DATEDIFF(hour, 0, EVENT_DATETIME), 0)
)
For March 17th, 2010:
SELECT COUNT(*) / 24
FROM EVENTS_ALL_RPT_V1
WHERE EVENT_NAME = 'Login'
AND EVENT_DATETIME >= CONVERT(DATETIME, '2010-03-17 00:00:00', 120)
AND EVENT_DATETIME < CONVERT(DATETIME, '2010-03-18 00:00:00', 120)