SQL Server : random date in specific range (including random hours, minutes,...) - sql-server

I would like to create a random date for a SQL Server update query. I found a lot examples for random days or something similar but I couldn't find something which creates a random date with random date, hours, minutes, seconds AND milliseconds.
This is what I use to create the date randomly but it always gives me 00 as hour, minute, seconds and milliseconds and I don't know how I can randomize them as well.
This is my query:
declare #FromDate date = GETDATE()-2
declare #ToDate date = GETDATE()-1
UPDATE ACCOUNTS
SET dateFinished=
dateadd(day, rand(checksum(newid())) * (1 + datediff(day, #FromDate, #ToDate)), #FromDate)

This is how I'd do it:
Work out the number of seconds between from and to
Get a random number between zero and the number of seconds
Add that random number to the FromDate
Finally randomise the number of milliseconds
DECLARE #FromDate DATETIME = DATEADD(DAY, -2, GETDATE())
DECLARE #ToDate DATETIME = DATEADD(DAY, -1, GETDATE())
DECLARE #Seconds INT = DATEDIFF(SECOND, #FromDate, #ToDate)
DECLARE #Random INT = ROUND(((#Seconds-1) * RAND()), 0)
DECLARE #Milliseconds INT = ROUND((999 * RAND()), 0)
SELECT DATEADD(MILLISECOND, #Milliseconds, DATEADD(SECOND, #Random, #FromDate))

declare #FromDate dateTIME = '2014-01-01'
declare #ToDate dateTIME = '2014-12-31'
select top 100 dateadd(day,rand(checksum(newid()))*(1+datediff(day, #FromDate, #ToDate)), #FromDate) FROM Tabled(give your table name)

SELECT dateaddDATEADD(second,
second, (rand()*60+1),
DATEADD(minute,
(rand()*60+1) ,
DATEADD(day,
(rand()*365+1),
DATEADD(year,
-1,
getdate()))) )

Related

Want to get time in my dates as multiple of 5 in SQL

Declare #StartDate DATETIME = GetDate()
DECLARE #increase INT = 5;
DECLARE #EndDate DATETIME = (SELECT DATEADD(mi, #increase, #StartDate))
select #StartDate,#EndDate
In above query I have increased the current time by 5 min. Now What I want is if the query returns 2020-12-16 09:26:16.103 as start time and 2020-12-16 09:31:16.103 as end time the start time should automatically becomes 2020-12-16 09:25:16.103 and end end time will get increase accordingly by 5 minutes. I hope I am clear.
The answer to above question is below. Postiong so that it will help others
Declare #StartDate DATETIME = GetDate()
set #StartDate=(select dateadd(minute, datediff(minute, '1900-01-01', dateadd(second, 150, #StartDate))/5*5, 0))
DECLARE #increase INT = 5;
DECLARE #EndDate DATETIME = (SELECT DATEADD(mi, #increase, #StartDate))
select #StartDate,#EndDate

Recursive Start of Week Query with SUM

I am looking to get the sum of hours worked by week for n weeks in a single result. I came across this little gem that will provide a list of weeks going back n weeks from the current day using a recursive query.
DECLARE #dt DATE = '1900-01-01';
declare #startDate datetime , #endDate datetime
set #startDate = DATEADD(WEEK, DATEDIFF(WEEK, #dt, CURRENT_TIMESTAMP)-10, #dt)
set #endDate = DATEADD(WEEK, DATEDIFF(WEEK, #dt, CURRENT_TIMESTAMP)-1, #dt)
;with T(startday) as
(
select #startDate as startday
union all
select startday + 7
from T
where startday < #endDate
)
select startday as [StartDate], DATEADD(DD, 7, startday) AS [EndDate] from T
If I could use a similar recursive query that would be great. Other wise, I can build a big query with a union of each date range. I have spent more time than I would like to admit on this.
If I try.
DECLARE #monDT DATE = '1900-01-01';
DECLARE #startDate DATETIME , #endDate DATETIME
SET #startDate = DATEADD(WEEK, DATEDIFF(WEEK, #monDT, CURRENT_TIMESTAMP)-10, #monDT)
SET #endDate = DATEADD(WEEK, DATEDIFF(WEEK, #monDT, CURRENT_TIMESTAMP), #monDT)
;WITH T(startDay, endDay, StartDateTime, FinishedDateTime, ActualDurationHours)
AS (
SELECT
#startDate AS startDay,
#endDate AS endDay,
[WorkOrderTrade].[StartDateTime],
[WorkOrderTrade].[FinishedDateTime],
[WorkOrderTrade].[ActualDurationHours]
FROM [WorkOrderTrade]
WHERE [WorkOrderTrade].[TradeContactID] = 783
AND [WorkOrderTrade].[StartDateTime] > #startDate
AND [WorkOrderTrade].[FinishedDateTime] < #endDate
UNION ALL
SELECT
startDay + 7,
endDay,
StartDateTime,
FinishedDateTime,
ActualDurationHours
FROM T
WHERE startDay < #endDate
)
SELECT TOP (100)
startDay,
DATEADD(DD, 7, startday) AS endDay,
SUM(ActualDurationHours)
FROM T
GROUP BY startDay, endDay
It SUMs the total hours across the whole date range as per the recursive portion of the query. I need to come up with a way of filtering the hours in that recursive portion based on the startDay and endDay of each week. Something like the following would be good but you are not allowed to accumulate in the recursive portion.
SELECT
startDay + 7,
StartDateTime,
FinishedDateTime,
(SELECT SUM(ActualDurationHours) FROM [WorkOrderTrade] WHERE [WorkOrderTrade].[TradeContactID] = 783 AND (StartDateTime > startDay AND FinishedDateTime < DATEADD(DD, 7, startDay)))
FROM T
WHERE startDay < #endDate
Is there a way or do I need to build a large UNION query?
Persistence pays off but I had to go out of that box that I was stuck in and use a temporary table and a WHILE loop.
DECLARE #monDT DATE = '1900-01-01';
DECLARE #startDate DATETIME , #endDate DATETIME, #startOfWeek DATETIME
SET #startDate = DATEADD(WEEK, DATEDIFF(WEEK, #monDT, CURRENT_TIMESTAMP)-10, #monDT)
SET #endDate = DATEADD(WEEK, DATEDIFF(WEEK, #monDT, CURRENT_TIMESTAMP)+1, #monDT)
SET #startOfWeek = #startDate
CREATE TABLE #tmpDuration (
StartDate DATETIME,
EndDate DATETIME,
LoggedHours NUMERIC(18,7)
)
WHILE #startOfWeek < #endDate
BEGIN
INSERT INTO #tmpDuration
SELECT
#startOfWeek,
DATEADD(DD, 7, #startOfWeek),
SUM([WorkOrderTrade].[ActualDurationHours])
FROM [WorkOrderTrade]
WHERE [WorkOrderTrade].[TradeContactID] = 783
AND [WorkOrderTrade].[StartDateTime] > #startOfWeek
AND [WorkOrderTrade].[StartDateTime] < DATEADD(DD, 7, #startOfWeek)
SET #startOfWeek = DATEADD(DD, 7, #startOfWeek)
END
SELECT * FROM #tmpDuration
DROP TABLE #tmpDuration

How to get last six month of data from DB using SQL Server?

I have tried many different queries that already given here, but it also shows previous year data, for example, if use this query
Dateadd(Month, Datediff(Month, 0, DATEADD(m, -6, current_timestamp)), 0)
or
DATEADD(m, -6, current_timestamp)
These will result in the last six months. In my case, I want to print the last six month data. But the problem is if there is a data with the same date and different in the year will also result with these query eg (the above query returns the result of '2018-03-27 10:04:52.537' and if there is a data with '2017-03-27 10:04:52.537' will also come with the result). Can anyone help me?
here is my query
DECLARE #date6MonthAgo DATETIME = DATEADD(m, -6, current_timestamp)
DECLARE #totalCount INT = (SELECT COUNT(*)
FROM [PSA].[ProductionOrder]
WHERE CreatedDate >= #date6MonthAgo)
DECLARE #openCount INT = (SELECT COUNT(*)
FROM [PSA].[ProductionOrder]
WHERE DocumentStatusCode=7
AND CreatedDate >= #date6MonthAgo )
SELECT #date6MonthAgo, #totalCount, #openCount
Try something like this, after putting in the correct IDcolumn, just to verify for yourself the dates that are being returned
DECLARE #date6MonthAgo DATETIME = DATEADD(m, -6, current_timestamp);
SELECT #date6MonthAgo;
SELECT CreatedDate, keycolumnID
FROM [PSA].[ProductionOrder]
WHERE DocumentStatusCode=7
AND CreatedDate >= #date6MonthAgo
ORDER BY CreatedDate;
You can use this for find the last 6 month data from current date,
DECLARE #fromdate as datetime, #todate as datetime
set #fromdate = (select DATEADD(month, -6, getdate()))
set #todate = getdate()
SELECT CreatedDate, keycolumnID
FROM [PSA].[ProductionOrder]
WHERE DocumentStatusCode=7
AND cast(CreatedDate as date) between cast(#fromdate as date) and cast(#todate as date)
ORDER BY CreatedDate;
If you want find last 6 month date from a specific date, so you can set that date in #fromdate and #todate parameters like this,
set #fromdate = (select DATEADD(month, -6, #Yourdate))
set #todate = #Yourdate

SQL Sever - Datediff, hours, but exclude Saturday/ Sundays

I'm wondering how to calculate the "number of hours" between two timestamps (2016-02-24 17:30:00 and another, for instance) in SQL server- but excluding Saturday and Sunday's full 48 hour period, if crossed.
This isn't quite the same as pure business hours, but sort of. The reason for this is long-winded and unnecessary.
EDIT: I can also say that the end-date will always be during the week. So really ... the "start date" can simply be transmuted to Monday midnight, if on Sat/ Sun ... then maybe a function include the total week count...
DATEDIFF(Week, date, date2) will return the number of week boundaries that are crossed between the two dates. For SQL Server, this means how many Sundays are between the dates (as opposed to the number of 7 day periods are between them). This means, that if you can indeed assume that start and end date will not be a saturday or sunday, you can subtract 48 X DATEDIFF(Week, date, date2) from your normal DATEDIFF call and that should give you what are after.
I would use the below code
declare #NumberOfHours int
declare #StartTime datetime
declare #EndTime datetime
set #StartTime = '2017-02-02 17:30:00.000'
set #EndTime = '2017-02-07 00:00:00.000'
set #NumberOfHours = DATEDIFF(HOUR,#StartTime,#EndTime)
if(datepart(WEEKDAY, #StartTime)=1)
begin
set #NumberOfHours = #NumberOfHours DATEDIFF(HH,#StartTime,#EndTime)%24
end
else if(datepart(WEEKDAY, #StartTime)=7)
begin
set #NumberOfHours = #NumberOfHours - DATEDIFF(HH,#StartTime,#EndTime)%24
set #NumberOfHours = #NumberOfHours - 24
end
else
begin
set #NumberOfHours = #NumberOfHours - datediff(ww,#StartTime,#EndTime)*48
end
print #NumberOfHours
I would use a calendar table (ex. dbo.DateDimension, ref https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/):
CREATE TABLE dbo.DateDimension
(
DateKey INT NOT NULL PRIMARY KEY,
[Date] DATE NOT NULL,
[Day] TINYINT NOT NULL,
DaySuffix CHAR(2) NOT NULL,
[Weekday] TINYINT NOT NULL,
WeekDayName VARCHAR(10) NOT NULL,
IsWeekend BIT NOT NULL,
IsHoliday BIT NOT NULL,
...
)
and, also, following query:
SELECT SUM(
CASE
WHEN dd.[Date] = CONVERT(DATE, #StartDate) THEN DATEDIFF(MINUTE, #StarDate, DATEADD(DAY, 1, dd.[Date]))
WHEN dd.[Date] = CONVERT(DATE, #EndDate) THEN DATEDIFF(MINUTE, dd.[Date], #EndDate)
ELSE 24 * 60 -- Full day
END) / 60 AS SumOfHours
FROM dbo.DateDimension dd
WHERE dd.[Date] >= CONVERT(DATE, #StartDate) AND dd.[Date] <= CONVERT(DATE, #EndDate)
AND dd.IsWeekend = 0
Above query will compute total amount of minutes for requested period of time and then it will divide by 60 to get number of hours.

Calculate 5 months before a date value

I have a query that outputs a date, and I'd like to add an additional column that represents the date 5 months prior to that date. So if the output value is 2012-06 then I want to show 2012-01.
SELECT
unnamed_date_column,
5_months_earlier = DATEADD(MONTH, -5, unnamed_date_column)
FROM dbo.unnamed_table;
If you are storing these as varchar (which you must be if they are in yyyy-mm, and you should stop doing that), then you can do this:
SELECT
unnamed_date_column,
5_months_earlier = DATEADD(MONTH, -5, unnamed_date_column)
FROM
(
SELECT unnamed_date_column = CONVERT(DATETIME, unnamed_varchar_column + '-01')
FROM dbo.unnamed_table
) AS x;
Of course, that could generate an error, because if you chose the wrong data type for this column, anybody could have entered 2013-13 or 1623-99 or who_dat into this column...
select [column]
from [table]
where [datecol] between DATEADD(month, -5, getdate()) and getdate()
After computing the start date of the first month (#Start) and the end date (#End) of the last month:
DECLARE #CurrentDate SMALLDATETIME; -- Or DATE[TIME][2][OFFSET]
SET #CurrentDate = GETDATE(); -- 2013-10-05
DECLARE #Start SMALLDATETIME, #End SMALLDATETIME;
SET #Start = DATEADD(MONTH, (DATEDIFF(MONTH, 0, #CurrentDate) - 4), 0);
SET #End = DATEADD(MONTH, (DATEDIFF(MONTH, 0, #CurrentDate) + 1), 0);
SELECT #Start AS [#Start], #End AS [#End];
/*
#Start #End
---------- ----------
2013-06-01 2013-11-01
*/
you could filter the rows using these predicates:
SELECT ...
FROM ...
WHERE SomeDateColumn >= #Start AND SomeDateColumn < #EndDate;
try this one:
DECLARE #DT DATETIME = GETUTCDATE()
SELECT CONVERT(VARCHAR(7),#DT, 120) AS TODAY_DATE, CONVERT(VARCHAR(7),DATEADD(MM,-5,#DT), 120 ) AS BEFORE_5_MONTHS

Resources