Update query to find and change portion of MS SQL DateTime - sql-server

I have various datetime stamps on a expiration field (datetime). The datetime in that field for each record varies. For example,
2015-12-31 04:59:00:000, 2014-12-31 17:00:00:000, 2020-12-15 04:00:00:000
Trying to write a query to find all datetime that have an ENDING that is not equal != to 05:00:00:000.
Then an update query to update the end of the stamp to 05:00:00:000, leaving the front as is.
Some example changes, from - to:
From:
2015-12-31 04:59:00:000, 2014-12-31 17:00:00:000, 2020-12-15 04:00:00:000
To:
2015-12-31 05:00:00:000, 2014-12-31 05:00:00:000, 2020-12-15 05:00:00:000
Here is what I'd like to see:
UPDATE table_name
SET table_name.expire_field = keep_front_date_portion + '05:00:00.000'
WHERE table_name.expire_field = date_portion_ignore and time_portion != '05:00:00.000'
Not sure how this would be written correctly in MS SQL 2008 syntax?
I found this post but from what I can tell it needs a timestamp that does not vary.

We can use DATEADD/DATEDIFF to reset just the time portion of a datetime value
UPDATE table_name
SET expire_field =
DATEADD(day,DATEDIFF(day,'19000101',expire_field),'1900-01-01T05:00:00')
WHERE DATEPART(hour,expire_field) != 5 or
DATEPART(minute,expire_field) != 0 or
DATEPART(second,expire_field) != 0
But you may find it easier to just skip the WHERE clause and let it update the entire table - you're not going to be able to benefit from indexes here anyway.
In the DATEADD/DATEDIFF pair, the date is arbitrary. First, the inner DATEDIFF asks "how many whole days have passed since some date", and then the DATEADD adds that same number of days onto some date at 5am.

Related

Convert Wed Oct 14 08:00:00 CDT 2020 format to DateOnly and Time Only

We receive a csv file that has a column in this date format -- Wed Oct 14 08:00:00 CDT 2020, along with a column that has a count for each date/time
I am using an SSIS package to grab the file and import this data into a sql table, then I can format it the way I need to and then actually export the data in the format needed.
If there is a way to do this all within one SSIS package I am all ears but currently I am working on just getting the data into SQL and converted to the right format so that I can export it.
I need to get that file and convert that date format and split it up into two separate columns
One column will be just the date in this format 2020-10-14 00:00:00.000
One column will be just the time in this format 08:00:00.0000000
Updated to change the dates to match so it's not as confusing and also the error I am receiving when running the suggested code below.
Image of Error I'm recieving
Image of table with the data I am trying to convert
Image of table attributes
Screenshot of my screen when running a select * from the table I am pulling the data that I need converted
Screenshot of the error I receive when running the query by Aaron.
If this is the format it will always be in, and timezone is irrelevant, you can first try to convert it to a datetime, then you can extract the parts from that.
SET LANGUAGE us_english; -- important because not all languages understand "Oct"
;WITH src AS
(
SELECT dt = TRY_CONVERT(datetime, RIGHT(OpenedDateTime ,4)
+ SUBSTRING(OpenedDatetime, 4, 16))
--, other columns...
FROM [dbo].[VIRTUALROSTERIMPORT_Res_Import]
)
SELECT OpenedDateTime = CONVERT(datetime, CONVERT(date, dt)),
OnHour = CONVERT(time, dt)
--, other columns...
FROM src;
Results:
OpenedDateTime OnHour
-------------- ----------------
2020-10-14 08:00:00.0000000
If you need to shift from one timezone to another timezone, that's a different problem.
I was just showing the date formats, don't look so into the actual date examples I used. The time zone is irrelevant I just need the formats changed.
When I used The code Aaron suggested I got a conversion error: I'm assuming its because the columns are varchar in the table, but I cant get the dates to load as date formats bc SSIS keeps giving me truncated errors-- so I have to load it as varchar.
Below is the code I was running, I tweaked it to use the column and table names I am using.
SET LANGUAGE us_english; -- important because not all languages understand "Oct"
DECLARE #foo varchar(36) = 'Wed Oct 14 08:00:00 CDT 2020';
;WITH src(d) AS
(
SELECT TRY_CONVERT(datetime, RIGHT(#foo,4) + SUBSTRING(#foo, 4, 16))
)
SELECT OpenedDateTime = CONVERT(datetime, CONVERT(date, OpenedDateTime)),
onhour = CONVERT(time, OpenedDateTime)
FROM [dbo].[VIRTUALROSTERIMPORT_Res_Import];

Blank dates coming up as weird dates instead of NULL in SQL

I am importing data from postgres into sql server. Fields where data type is 'timestamp without (or with) time zone' i used datetimeoffset in sql table but couldn't create package with the same. So i changed the datatype as datetime.
Now, when I import data,all the dates and time are coming perfectly alright but where there is no data ( blank) then its displayed as some weird date instead of NULL in my SQL table.
Those weird dates are -
1899-12-30 00:00:00.000
1753-01-01 00:00:00.000
What am i missing and how to resolve this?
Maybe that's a simple thing but I am quite new to SQL so apologies if its really easy but any help is appreciated.
Thanks,
AP
Suppose your meaningful data is from 2000 onwards, then run a update statement like:
update table
set column = NULL
where column < cast('01-01-2000' as datetime)

Concatenate 2 x fields to make a Date

I have 2 x fields T1.period and T1.year both have data type smallint
Using SQL Management Studio 2014 how may I Concatenate them AND return result as a DATE type?
Also, T1.period has values 1 to 12 how may I pad this out to 01 to 12 ... or will changing to date type sort this out?
Much appreciated!
Sample data ...
period yr
1 2015
2 2009
12 2009
11 2010
10 2011
Result will be ...
Date
01/01/2015
01/02/2009
01/12/2009
01/11/2010
01/10/2011
Thanks!
Looks terrible struggling to get it into lists - sorry :(
Converting Your Values The Old Fashioned Way
Assuming that your t1.period value actually just represents a month, you could consider just converting your values to strings and then converting that concatenated result into a date via the CAST() function :
SELECT CAST(CAST(t1.year AS VARCHAR) + '-' + CAST(t1.period AS VARCHAR) + '-1' AS DATE)
This will build a string that looks like {year}-{month}-1, which will then be parsed as a DATE and should give you the first date of the given month/year.
Using The DATEFROMPARTS() Function
SQL Server 2012 and above actually support a DATEFROMPARTS() function that will allow you to pass in the various parts (year, month, day) to build a corresponding DATE object, with a much easier to read syntax :
SELECT DATEFROMPARTS(t1.year,t1.period,1)
Additionally, if you needed a DATETIME object, you could use DATETIMEFROMPARTS() as expected.

converting start date to datetime as beginning of the day and end date to end of the day

Store PROCEDURE
--para--
#StartingDate DateTime = NULL,
#EndingDate DateTime = NULL
--condition --
dbo.callentry.CallDateTime BETWEEN ISNULL(#StartingDate,
dbo.callentry.CallDateTime) and ISNULL(#EndingDate,dbo.callentry.CallDateTime)
Question :
when i pass date '2012-09-17' from date picker as para #StartingDate, and the same as ending date . it is comparing 2012-09-17 00:00:00.000 to 2012-09-17 00:00:00.000 - will return no records
what i want is records in whole day 2012-09-17
Why not just use #StartingDate-1 then?
Or even DATEADD(d,-1,#StartingDate)
Or #EndDate + 1
Or even DATEADD(d,1,#EndDate)
DATEADD (Transact-SQL)
Returns a specified date with the specified number interval (signed
integer) added to a specified datepart of that date.
Try this:
dbo.callentry.CallDateTime >=ISNULL(#StartingDate,
dbo.callentry.CallDateTime) and dbo.callentry.CallDateTime <=ISNULL(#EndingDate,dbo.callentry.CallDateTime)
Also make sure dbo.callentry.CallDateTime this column datatype is also datetime
OR
Also reading from your question. I think when strt and end date are same you just need all the records for that day. if start and end date are same why cant you just use like below:
convert(date,dbo.callentry.CallDateTime) =convert(date,ISNULL(#StartingDate,
dbo.callentry.CallDateTime))
In case of sql server 2008 if below just convert both the sides to just date format annd compare

What's the best way to perform math on a floored date in SQL Server?

This is related to Floor a date in SQL server, but I'm taking it one step further:
I'm writing a query on a SQL Server table and I want to get all records for the current calendar year and the previous calendar year. So, right now, I'd want a query to return all records between January 1st, 2008 and today. But come January 1st, 2010, I want it to return records no older than 2009.
Essentially, I want to floor the current date to the beginning of the year and then subtract 1.
After rummaging through some SQL Server documentation, I came up with this:
WHERE create_date >= CAST((CAST(YEAR(GETDATE()) AS int) -1) AS varchar)
but it feels kind of ugly. Is there a better way?
Why not just use the year function on create_date as well?
WHERE YEAR(create_date) >= (YEAR(GETDATE()) -1)
This assumes (as you did) that there are no records in the database greater than today's date
I would suggest assigning a variable with the date lastyear-01-01, either by making an UDF for it, or something like
DECLARE #startOfLastYear DATETIME
SET #startOfLastYear = CAST(YEAR(GETDATE()) - 1 AS VARCHAR) + '-01-01'
Then do the query:
WHERE create_date >= #startOfLastYear
Because of two reasons:
Using YEAR() or any other function
on data from tables (i.e.
YEAR(create_date)) makes indices
unusable and decreases the
performance of the query
The variable name tells exactly what it is, and reading the code is easier.

Resources