Convert a text column to a datetime column - sql-server

How do I convert a column of type text to type date/time? I have the createdon column that I convert from UTC time to eastern time zone with day light savings time in consideration. This works. However, the createon column results in a type text. I need it in date and time.
Below is my SQL query. How exactly would you write the conversion within the existing query? This is for SQL Server. Thanks.
select [$Table].[field1] as [field1],
...,
[$Table].[createdon] at time zone 'UTC' at time zone 'Eastern Standard Time' as [createdon],
...,
[$Table].[fieldN] as [fieldN]
from [dbo].[TableA] as [$Table]

I was able to do the conversion by using the cast keyword and convert as a date type.

Related

What is the neat approach to combining the date and time value (both of datetime type)?

I am writing a SQL query on table that has 2 columns:
StartDate: type - datetime (example: 2022-01-22 00:00:00.000)
StartTime: type - datetime (example: 1900-01-01 21:30:00.000)
I want to combine both so as to get the datetime value (example: 2022-01-22 21:30:00.000)
I tried using the DATEADD function, but that expects an interval, which is not suitable for my requirement.
I also tried adding the dates using the + sign which seems to give correct result; and also tried converting the date to int and then doing the + followed by conversion to datetime. This doesn't give correct result.
What is the neat approach to combining the date and time value?
You can simply add the two parts, since the reference date for datetime is 1900-01-01. I.e., internally SQL-Server represents it by the number 0.
select
StartDate, StartTime,
StartDate + StartTime as StartDateTime
from t
See: http://sqlfiddle.com/#!18/0f0a7/2/0
The documentation for datetime (Transact-SQL) just says
Default value 1900-01-01 00:00:00
and
When the conversion is from time(n), the time component is copied, and the date component is set to '1900-01-01'.

Conversion of UTC time to LOCAL in SQL Query output

I'm struggling with a SQL query - a basic select statement with a UTC time conversion in the select output. I've done a bunch of searching on this and through all of that have arrived at the following query, but it does not seem to work for me.
SELECT [Id]
,[BaseSource]
,[Source]
,[Output]
,[SessionId]
,[Timestamp]
,(SELECT DATEADD(MILLISECOND,DATEDIFF(MILLISECOND,getutcdate(),GETDATE()),[Timestamp])) as LocalTime
FROM [MYDB].[dbo].[SystemOutput]
ORDER BY [Timestamp] DESC
This line is where the magic should be happening, but instead i get a exact match of the Timestamp column value, so no conversion happening at all:
(SELECT
DATEADD(MILLISECOND,DATEDIFF(MILLISECOND,getutcdate(),GETDATE()),[Timestamp]))
Does anyone know of how to get this working?
Thanks
First, understand that getdate() returns the local date and time of the server - not of the person running the query. If the server's time zone is set to UTC, then it will indeed return the UTC time.
Since you are running on SQL 2016, and you are asking for the UTC time converted to Pacific time, I suggest you use the built-in AT TIME ZONE statement, as follows:
SELECT [Id]
,[BaseSource]
,[Source]
,[Output]
,[SessionId]
,[Timestamp]
,[Timestamp] AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time' AS LocalTime
FROM [MYDB].[dbo].[SystemOutput]
ORDER BY [Timestamp] DESC
Note, the above assumes that the [Timestamp] field is a datetime or datetime2, and that it is a UTC-based value. The first AT TIME ZONE makes an assertion that the given value is in UTC, resulting in a datetimeoffset. The second AT TIME ZONE then converts from UTC to Pacific time.
If instead the field is already a datetimeoffset type, then the query is even simpler:
SELECT [Id]
,[BaseSource]
,[Source]
,[Output]
,[SessionId]
,[Timestamp]
,[Timestamp] AT TIME ZONE 'Pacific Standard Time' AS LocalTime
FROM [MYDB].[dbo].[SystemOutput]
ORDER BY [Timestamp] DESC
Also, don't be confused by the word "Standard" in the time zone identifier. That value covers both standard time and daylight time, as applicable in the Pacific time zone in the US and Canada.

SQL Server - Select between 2 dates of type DD/MM/YYYY

I want to query a datetime field using a range of dates provided in the format DD/MM/YYYY.
I know that to convert datetime to a DD/MM/YYYY format that I can use:
CONVERT(CARCHAR(10), ORDERDATE,103)`
And this works fine when querying a single date, eg:
SELECT DISTINCT
CONVERT(DATE, ORDERDATE),
CONVERT(CARCHAR(10), ORDERDATE,103)
FROM ORDERS
WHERE CONVERT(CARCHAR(10), ORDERDATE,103) = '19/10/2017'
Returns: 2017-10-19, 19/10/2017
However it does not work on a range of dates, eg:
WHERE CONVERT(CARCHAR(10), ORDERDATE,103) BETWEEN '17/10/2017' AND '19/10/2017'
Returns:
2014-02-05
2016-12-12
2013-04-30
I know there are hundreds of threads about SQL dates, but they all seem to be regarding reformatting the output and not preparing the input. Do I need to reformat my DD/MM/YYYY inputs?
To query a range of dates, use the DATE-datatype instead of VARCHAR.
If datatype of column ORDERDATE is DATETIME:
WHERE CONVERT(DATE, ORDERDATE) BETWEEN
CONVERT(DATE, '17/10/2017', 103) AND CONVERT(DATE, '19/10/2017', 103)
The conversion of ORDERDATE is only necessary if the start and end date are the same. (in this case, when no conversion is done, only dates with a time value of '00:00:00.000' will be returned)
EDIT:
To omit the conversion of ORDERDATE you can add the time to the dates and convert them to DATETIME instead of DATE, like this:
WHERE ORDERDATE BETWEEN
CONVERT(DATETIME, '19/10/2017 00:00:00') AND CONVERT(DATETIME, '19/10/2017 23:59:59.999');
Or even simpler, like suggested in #Used_By_Already's answer:
WHERE ORDERDATE >= '20171017' AND ORDERDATE < '20171020' --Note the end date is here +1 day
SQL Server date information should NOT be stored "in a format". If if they are literally stored in that format then they are NOT dates as far as the database is concerned (they are "strings" that look like dates) and you will have a nightmare to deal with if they are DD/MM/YYYY because they simply will not behave like dates should.
There are several specific data types in SQL Server for date/time information (datetime, datetime2, smalldatetime, date, time) but ALL of these do not store data in a human readable format at all. Instead they stored as groups of numbers, which will be displayed in a human readable manner, and in your case - by default - you are seeing then in DD/MM/YYYY format. A user in China might prefer to see a date in YYYY.MM.DD or in the USA as MM/DD/YYYY. This is possible because a human format is applied on top of the numbers that are stored before they get displayed.
So. In SQL Server there is a "safe" date literal in the form of 'YYYYMMDD' and this may be used without the need to CONVERT or CAST:
IF your [ORDERDATE] column is a date (or smalldatetime/datetime/datetime2) then this will work:
WHERE ORDERDATE BETWEEN '20171017' AND '20171019'
OR, you may explicitly convert a string to but you need a "style number" to be present to make these fully reliable. Style 103 for example is for DD/MM/YYYY
WHERE ORDERDATE BETWEEN CONVERT(date, '17/10/2017',103) AND CONVERT(date, '19/10/2017',103)
Although "between" has been used in the discussion above a far more reliable method of forming date ranges is to NOT use "between", instead do it this way:
WHERE ORDERDATE >= '20171017' AND ORDERDATE < '20171020'
With this pattern (note the second day is now +1) it does not matter which date precision is stored in the column. For example, see Bad habits to kick : mis-handling date / range queries

PostgreSQL : Converting timestamp without time zone to a specific timezone not working

I am trying to migrate a column in Postgres from Timestamp without time zone to a timestamp with time zone. I want to do it for German time, so I used the following query :
alter table table_name alter column uploaddate type TIMESTAMP WITH TIME ZONE USING uploaddate at time zone 'UTC+01:30';
Unfortunately it's not working, it's adding 2015-06-30 07:30:48.785+05:30. I am currently in India, which is +5.30. How can I specify to the query to do it with German time zone. Thank you.
What is the timezone of the timestamps stored in the table? That is, if there is a value such as 2016-09-22 07:30 in the table, in what timezone is 07:30? This is the timezone that you want to use, not your current local timezone. So e.g. if all timestamps are expressed in german timezone you should do something like:
alter table table_name
alter column uploaddate type TIMESTAMP WITH TIME ZONE
USING uploaddate at time zone 'Europe/Berlin';
Don't forget that you can run the above inside a transaction so that you can inspect the results before you commit them (of course this will lock the entire table and block all other concurrent queries for that table).

Compare 2 DateTime values in a WHERE clause

I have a very simple query. (I'm working in SQL Server 2008.) I'm trying to select all records from a view where their ModifiedOn column is greater than a specified date. The ModifiedOn column is a datetime format. So, I have:
DECLARE #date1 AS datetime = '2013-07-31 24.59.59.999'
SELECT
some_column
FROM dbo.some_view
WHERE ModifiedOn > #date1
SQL is throwing the following error, though:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value. Why is SQL thinking that one of my dates is a varchar, when I know that both of them are datetime formats? How do I fix it?
Datetime variable expects data to be in format of
YYYY-MM-DD HH:MM:SS.mmm
In your case you are trying to assign a value which is not a valid time. HH.MM.SS.mmm
Secondly a clock never strikes 24:00:00 it goes from 23:59:59.999 to 00:00:00.001.
Also in your case rather than juggling with seconds and milliseconds. just use date value and use the ANSI standard YYYYMMDD which is also sargable.
You could have written your above query something like
SELECT some_column
FROM dbo.some_view
WHERE ModifiedOn >= '20130801'

Resources