Update datetime values to same date but persist time - sql

I'm in a situation where I would like to update the date of all the values in the table to have the same day but persist the time of each record.
So these three dates...
8/28/2012 14:00:00
8/28/2010 12:00:00
8/28/2008 10:00:00
Should be turned into...
8/28/2012 14:00:00
8/28/2012 12:00:00
8/28/2012 10:00:00
UPDATE MySpecialTable
SET DateField = {...?};
Edit: Regardless of the day the date is on (i.e. 8/28/2012, 1/1/2012, 4/1/2012, etc), I want to persist the time and mass update all the day/month/year to a specific value.

DECLARE #Target DATETIME;
SET #Target = '20120828';
-- if the date is supposed to be today rather than hard-coded or parameterized:
-- SET #Target = DATEADD(DAY, DATEDIFF(DAY, '19000101', CURRENT_TIMESTAMP), '19000101');
UPDATE dbo.MySpecialTable
SET DateField = DATEADD(DAY, DATEDIFF(DAY, DateField, #Target), DateField);
This will work if the target date is before or after the value in the column.
Also, if you only care about time, you should consider using the TIME data type (SQL 2008+). This will make it easy to apply any date you want to the data at query time, without having to actually perform any updates.

Here is one way, assuming you are using SQL Server 2008 or greater:
update MySpecialTable
set DateField = cast(CURRENT_TIMESTAMP as date) + (DateField - cast(DateField as date))

Try this (updated to have the same date):
DECLARE #myDate DATETIME
SET #myDate = '2012-08-28T00:00:00.000'
UPDATE [MySpecialTable]
SET [DateField] = DATEADD(Day, 0-DATEDIFF(Day, 0, [DateField]), [DateField]) + #myDate
DATEADD(Day, 0-DATEDIFF(Day, 0, [DateField]), [DateField]) gets the
timestamp and makes the date to the min value (1/1/1900)
Add the above to the desired date in the variable

Related

How to show Current Date as Current Date ending at 3:00:00AM in SQL

I have a task that I need to show the current date time as ending at 3:00:00 AM at current date. For example, GETDATE() returns the current date time when executes. I need to show it as 9/5/2019 3:00:00 AM instead. Below is my code:
DECLARE #END_SHIFT AS DATETIME
SET #END_SHIFT = '06:00:00 AM'
SELECT
NUMBER_ID,
GETDATE() AS CURRENT_DT,
GETDATE() - #END_SHIFT AS END_SHIFT_DATE
FROM table
My issue when running this is it does not return as ending at 3:00:00AM. Please let me know your direction.
Thanks,
H
A bit of an odd request for sure but you could simply use DATEADD.
SELECT dateadd(hour, 3, convert(datetime, convert(date, getdate())))
If you really need a "hard" time, one option is to use format()
Example
Select format(GetDate(),'yyyy-MM-dd 03:00')
Returns
2019-09-05 03:00

Need help extracting SQL data for 2 previous days

I need to run a SQL script every night that extracts data from the previous 2 days. For example: On July 9 at 1am, the script runs and needs to extract data from July 8 and July 7. On July 10 at 1am, it needs to extract data from July 9 and July 8, etc.
The script is functional, in that it correctly extracts data for a fixed date range (by including the actual date range in the script), but I don't know how to make it do the "2 days prior" part.
Figuring this out is beyond me! Can anyone provide guidance?
Using SQL Server 2014
You can do:
where datecol >= convert(date, dateadd(day, -2, getdate())) and
datecol < convert(date, getdate())
That said, I would be very wary about putting this logic directly into a query. I would create a stored procedure in SQL Server and have it take #fromdate and #todate arguments.
Then, schedule a job that does the above calculation and calls the stored procedure with the right parameters.
One day, when the server is down or the logic fails, you will appreciate having the flexibility to specify the date range yourself.
I would create three variables.
#today: is the current datetime cast to a date to set it to midnight
#startDate: first/start date where I would use the DATEADD function to subtract two days
#endDate: end date that you can subtract 1 second from today
This should get you a date range of 2019-07-07 00:00:00.000 to 2019-07-08 23:59:59.000
DECLARE #today DATETIME = CAST(GETDATE() AS DATE);
DECLARE #startDate DATETIME = DATEADD(DAY, -2, #today);
DECLARE #endDate DATETIME = DATEADD(SECOND, -1, #today);
Time is usually very critical when working with dates, make sure your start date starts at the beginning of the day and your end date ends at the very end of the day!
Your query would then look like:
SELECT *
FROM my_table
WHERE my_date_column BETWEEN #startDate AND #endDate

Get rows having a datetime less than or equal to today ignoring time

I have a datetime field and would like to select the records having a date less than or equal to today but ignoring the time part of it.
My datetime field is as below:
2019-05-17 13:31:15.900, 2019-05-16 13:32:17.277, 2019-05-24 15:20:03.823
I would like to fetch only the rows with datetime 2019-05-17 13:31:15.900 and 2019-05-16 13:32:17.277 ignoring the time part.
Any idea of how to do that in sql server?
Simply, just cast both, your column and todays date to DATE:
SELECT * FROM MyTable
WHERE CAST(dt AS DATE) <= CAST(GETDATE() AS DATE)
You may try casting GETDATE() to a date type, to compare against tomorrow at midnight:
SELECT *
FROM yourTable
WHERE dt < CAST(DATEADD(day, 1, GETDATE()) AS date);
-- earlier than tomorrow at midnight
The date when this answer was written was 17-June-2019, so the above query would return any record whose datetime is strictly less than 18-June-2019 at midnight. The latest record would therefore be '2019-06-17 23:59:59'.

SQL Server - Check if given date+time is between two datetime variables by exact date+time

I have two datetime columns in a DB table: #Start and #End.
Both columns contain the date and time, for example:
#Start: 2018-10-01 19:00:00
#End: 2018-10-10 23:59:00
I want to know if the current date is exactly between both datetimes considering the dates and the times.
So, 2018-10-08 16:37 and 2018-10-10 23:59:00 would match this range
and 2018-10-11 00:00:00 would not.
(In this case this date is one minute later than the End date, so it is not between my datetime range).
SELECT Id FROM Table1 WHERE GETDATE() BETWEEN Start AND End
I don't use GETDATE() in real code, I use an argument. The problem is that current date argument may contain seconds and milliseconds like 23:59:59.123. My code treats such date as not conforming given range. But I don't care about s/ms.
Is there a workaround?
Update:
The precision I want to achieve is in minutes. So I do not even need to take in account the seconds nor the milliseconds. The date time format I would be working on would be 'yyyy-MM-dd hh-mm' but I do not know how to use the BETWEEN clause converting the Start and End to the shown format so I can compare the dates.
You would seem to want this logic:
WHERE GETDATE() >= Start
AND GETDATE() < DATEADD(minute, 1, End)
Assuming that the time part of End is 23:59:00 it covers all possible values between 23:59:00 and 23:59:59.999...999.
SELECT Id FROM Table1 WHERE GETDATE() BETWEEN '2018-10-01 19:00:00' AND '2018-10-10 23:59:00'
TRY
SELECT Id FROM Table1 WHERE
CONVERT(varchar(16),GETDATE(),121) BETWEEN
CONVERT(varchar(16),[Start], 121)
AND
CONVERT(varchar(16),[END],121);
Example of rounding without strings
DECLARE #GetDateMinutes as datetime2;
DECLARE #X as datetime2 = getdate();
--round to minutes, could be made into a function
SET #GetDateMinutes = dateadd(minute,datepart(minute,#x),dateadd(hour, datepart(hour,#x),cast(CAST(#x as date) as datetime2)))
select #x, #GetDateMinutes
Truncate the seconds using the technique described here to avoid all string conversions, then just do your comparison. Here's a fully contained example that uses cross apply and values to encapsulate the truncation logic for start and end:
-- truncate minutes from current date time
declare #currentDateTime datetime2(0) = DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), N'2018-10-01 23:58:32.912')), 0);
select #currentDateTime as CurrentDateTime
, a.*
from (values -- create a table of dummy values
(Convert(datetime2(3), N'2018-10-01 19:48:14.735'), Convert(datetime2(3), N'2018-10-10 02:00:00.000'))
, (Convert(datetime2(3), N'2018-10-01 22:43:19.532'), Convert(datetime2(3), N'2018-11-01 12:17:26.663'))
) as a (StartDateTime, EndDateTime)
cross apply (values(
-- truncate minutes from start date time
DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), a.StartDateTime)), 0)
-- truncate minutes from end date time
, DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), a.EndDateTime)), 0)
)) as b (StartDateTimeWithoutSeconds, EndDateTimeWithoutSeconds)
where #currentDateTime between b.StartDateTimeWithoutSeconds and b.EndDateTimeWithoutSeconds;
Your data appears to already have the s/ms truncated from start and end but figured I'd apply the same logic to all values involved just to be consistent. Here's the formula for stripping s/ms without all the "noise" from the example:
DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), <SomeDateTime>)), 0)

How to change both date and time in a datetime in SQL

I try to set the time and date in my query based one the following conditions:
if time in MyDate < 9:00 then set the time to 9:00
If time in 9:00 < MyDate < 15:00 then set the time to 16:00
If time is MyDate > 15:00 then set the time to 9:00 and the day to day+1
I have the two first conditions in place and works fine, but cannot combine changes in both time and date. How can I do that?
The code below works fine for the two first conditions!
Case When cast(MyDate as TIME) < '09:00:00' Then DATEADD(Hour, 9, CAST(CAST(PayoutDtApplication As Date) As Datetime))
Case When cast(MyDate as TIME) < '09:00:00' Then DATEADD(Hour, 9, CAST(CAST(PayoutDtApplication As Date) As Datetime))
THanks
This is a guess, based on the following comment:
this numbers can varries based on the data I get, just wanted to say I need to set the time to 9:00 and day+1 for all dates I get. I have different dates.
I'm guessing that regardless of the time, the OP wants to change the value to the following date at 09:00:00.
If so, one way to achieve it would be:
SELECT DATEADD(HOUR, 33, CONVERT(date,YourDateColumn)) AS NewDate
FROM YourTable;
Again, this is guesswork. If the OP elaborates, I'll be happy to expand my answer, or remove it if it's irrelevant.
Edit: Based on the OP's new logic from their edit:
CREATE TABLE #Sample (YourDate datetime2(0));
INSERT INTO #Sample
VALUES ('2018-05-09T08:57:00'),
('2018-05-09T14:26:37'),
('2018-05-09T19:24:01');
GO
SELECT YourDate,
CASE WHEN CONVERT(time, YourDate) < '09:00:00' THEN DATEADD(HOUR,9,CONVERT(datetime2(0),CONVERT(date,YourDate)))
WHEN CONVERT(time, YourDate) > '15:00:00' THEN DATEADD(HOUR,33,CONVERT(datetime2(0),CONVERT(date,YourDate)))
ELSE DATEADD(HOUR,15,CONVERT(datetime2(0),CONVERT(date,YourDate))) END AS NewDate
FROM #Sample;
GO
DROP TABLE #Sample;
The double CONVERT (CONVERT(datetime2(0),CONVERT(date...) is because the data type date isn't compatible with DATEADD(HOUR.... I have used datetime2 as this should be used over datetime now.