Group by 24hr Period starting at 7:00 AM - sql-server

I have some high frequency data that I need to group by 24hr period starting at 7:00 AM. How can I do that?
For example, there is a timestamp every 5 minutes and I want to group it by day, but each day starts at 7:00 AM.
How would I go about doing that?
SQL Server 2016.

I am going to presume your time is probably in UTC.
I would look at converting the time to the timezone you need. Then it gives you more options of how you want to deal with the data, also you could customize the report for people in different zones. For some info about timezones I found this stackoverflow post.
Convert datetime value from one timezone to UTC timezone using sql query
Something like this in an group by clause should work. The code below says if the hour is under 8 then it's still yesterday, else it's really today. You would need to replace the getdate() with the correct column. If I Am correct about that the times are in UTC/GMT I would recommend looking at just converting it to the timezone you want.
case when datepart(hh, getdate())<8 then
cast((DATEADD(day, -1, getdate())) as date)
else
cast(getdate() as date)
end

Related

Executing a sql script every month for the first and last 16 days.

I have a script that I have had to ran manually a few times but now it looks like it will need to be ran twice a month. The problem is the dates are dynamic and the job needs to run on the 1st and 16th of every month but it will need to pull all data from the last 16 days. So for example, if we run it on the first of this month (Jan) the dates would be >= 2016-12,16 and <= 2016-12-31
I have been looking at the date function sql server has but I am not really sure if it will work for what I need.
I would look at DateAdd, and add a negative number of dates to the value to go back 16 days.
DATEADD(DAY, -16, GETDATE()).
I would personally just run a script with cron and set it up to run on the 1st and the 16th of every month.

Is there any advantage to GETDATE() + x over DATEADD(day,x,GETDATE())?

As I understand it, there are 2 main ways to add/subtract days to a date/datetime in MS SQL Server:
For example, to add one day, there is:
GETDATE() + 1
DATEADD(day, 1, GETDATE())
Is there any advantage or disadvantage to either approach?
No real advantages except that when you use GETDATE()+1 we don't really know what you are adding (days, months, hours, seconds?).
DATEADD makes it explicit and also ease your job when you need to add something else than days.
In my opinion GetDate()+1 will add just 1 day to current date, there is no way to add months or years in current date, but if you want to add month, year, hours etc o than DATEADD provide various options using that you can get past\future dates based on current date.
So if you are trying to add just day, than both would have same impact.
Thanks
Suresh

Calculate Facebook likes, comments, and shares for different time zones from saved UTC

I've been struggle with this for a while and hope someone can give me an idea to tackle this.
We have a service that goes out and collects Facebook likes, comments, and shares for each status update multiple times a day. The table that stores this data is something like this:
PostId EngagementTypeId Value CollectedDate
100 1(for likes) 10 1/1/2013 1:00
100 2 (comments) 2 1/1/2013 1:00
100 3 0. 1/1/2013 1:00
100. 1. 12 1/1/2013 3:00
100. 2. 3. 1/1/2013 3:00
100. 3 5. 1/1/2013 3:00
Value holds the total for each engagement type at the time of collection.
I got a requirement to create a report that shows new value per day at different time zones.
Currently,I'm doing the calculation in a stored procedure that takes in a time zone offset and based on that I calculate the delta for each day. If this is for someone in California, the report will show 12 likes, 3 comments, and 5 shares for 12/31/2012. But if someone with the time zone offset of -1, he will see 10 likes on 12/31/2012 and 2 likes on 1/1/2013.
The problem I'm having is doing the calculation on the fly can be slow if we have a lot of data and a big date range. We're talking about having the delta pre-calculated for each day and stored in a table and I can just query from that ( we're considering SSAS but that's for the next phase). But doing this, I would need to have the data for each day for 24 time zones. Am I correct (and if so, this is not ideal) or is there a better way to approach this?
I'm using SQL 2012.
Thank you!
You need to convert UTC DateTime stored in your column to Date based on users UTC time. This way you don't have to worry about any table that has to be populated with data. To get users date from your UTC column you will use something like this
SELECT CONVERT(DATE,(DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), '01/29/2014 04:00')))
AS MyLocalDate
The select statement above figures out Local date based on the difference of UTC date and local Date. You will need to replace GETDATE() with users DATETIME that is passed in to your procedure and replace '01/29/2014 04:00' with your column. This way when you select any date from your table it will be according to what that date was at users local time. Than you can calculate other fields accordingly.

Handling timezones

I have a view on a database that gets me the status of some work items. For example, it gets a start date, and end date, and then does some maths based on GetDate() to return me a 'Work Remaining' type of answer.
Problem is, the database server is in the United States and I am sitting in Australia.
So, the time here now is 19h33 on the 20th of July, and GetDate() on the server returns 02h33 on the 20th.
How should timezones be handled? Should my userprofile have a timezone field, and I deduct or add hours on the client side? Problem with that is that everything needs to manipulate dates and times. That is, the application, and any reports.
I have a view, for example, that returns me the remaining hours of a particular piece of work. It uses GETDATE() to calculate this:
ALTER VIEW [dbo].[vwSprintSummary] AS
SELECT
SprintId,
SprintName,
MIN(DateValue) AS FirstSprintDate,
MAX(DateValue) AS LastSprintDate,
SprintEndDate,
COUNT(DISTINCT PersonId) AS AssignedPeople,
COUNT(DISTINCT ProjectResourceId) AS AssignedRoles,
SUM(AssignedProductiveHours * CanBurnDown) AS Capacity,
SUM(CASE WHEN CAST(GETDATE() AS DATE) <= DateValue THEN AssignedProductiveHours* CanBurnDown ELSE 0 END) AS RemainingCapacity
FROM [vwSprintDailyBreakdown]
GROUP BY SprintName, SprintId, SprintStartDate, SprintEndDate
GO
Somehow, I need to change the GetDate() to a 'DATEADD...' so that I can get answers in the correct time zone?
In this case, a 'fix' would be to change the GETDATE() to DATEADD(HOUR, 17, GETDATE())
Hardcoded, I know, but in essence, that would fix a problem.
Is there no way to somehow tell the server my zone, and get it to return dates based on my location?
Generally speaking, store all information in your database in UTC and do all business-logic processing in UTC too, only convert to a local timezone in your presentation-logic layer - this approach will save you no-end of trouble, and means that the database server can (and should) remain blissfully unaware of your timezone.
In my own projects I tend to trust the webserver's clock rather than the database server's clock, so I never use GETUTCDATE() on the SQL Server, instead I provide all dates and times to the as a SQL parameter, e.g. a query to find "orders placed today" will provide its own definition of "today" (i.e. by providing a minimum and maximum date/time value).

Setting Report date parameters

I have a report written in visual studio running on a SQL server 2005 DB.
I want it to automatically apply the day before's date
- start at 00:00:00 and end 23:59:59
From my pic the code I use is
=DateAdd(Dateinterval.day, -1, Now()) for the start date
and for end date I use
=Now()
These values get me a report for the last 24 hours but I want to get the report to run just for the 24 hours of the previous day. How would I do this?
I think you should be using Today() instead of Now().
Both will give today's date, but Today() will not include any time portion.
You should only use one date paramater being yesterday =DateAdd(DateInterval.Day, -1, Today()).
Then to use this your data should be truncated to the date only and filtered to equal this parameter getting yesterday only irrispective of the time.

Resources