Currently i have a column called date as varchar instead of date time. the format is currently 'sep12'. How can i transfer this to a date type?
I know this is the template but I'm not sure what to change the numbers to due to my current format as MMMYY.
CAST (
SUBSTRING(date, 3, 2) + '/' +
SUBSTRING(date, 1, 2) + '/' +
SUBSTRING(date, 5, 4)
AS DATETIME)
any help would be greatly appreciated
At the moment when ordering by the date field it is ordering like apr09, apr10. aug09, aug10 but I need it to be in year order
First, storing dates in this manner is a terrible idea. But if you know that the year will always start with 20 then you can use something like this (see SQL Fiddle Demo):
declare #dt varchar(10) = 'Sep12'
select convert(datetime, left(#dt, 3) + '01 20' + right(#dt, 2), 100)
If pulling data from your table:
select convert(datetime, left(yourDateField, 3) + '01 20' + right(yourDateField, 2), 100)
from yourTable
Related
In my Microsoft SQL Server database, every date or datetime is represented as a decimal(17,0) value.
For example: 20210722054500000 would translate to 2021-07-22 05:45:00:000
I already came up with an solution to convert this:
SELECT
CONVERT(datetime, (SUBSTRING(CAST(20210722054500000 AS varchar(20)), 1, 4) + '-' +
SUBSTRING(CAST(20210722054500000 AS varchar(20)), 5, 2) + '-' +
SUBSTRING(CAST(20210722054500000 AS varchar(20)), 7, 2) + ' ' +
SUBSTRING(CAST(20210722054500000 AS varchar(20)), 9, 2) + ':' +
SUBSTRING(CAST(20210722054500000 AS varchar(20)), 11, 2) + ':00'), 120)
It works, but I feel there should be an better solution to convert this.
So my question is has anybody an approach that requires less code or would be better in regards to performance?
You can do it without casts and string functions, using datetimefromparts:
declare #input decimal(17,0) = 20210722054500000
select DATETIMEFROMPARTS(
#input/10000000000000 ,-- year
#input/100000000000 % 100 ,-- month
#input/1000000000 % 100 ,-- day
#input/10000000 % 100 ,-- hour
#input/100000%100 ,-- minute
#input/1000%100 ,-- seconds
#input%1000 -- milliseconds
)
One way is to extract the parts using a simple set of substrings. Given this table and data:
CREATE TABLE dbo.WhoDesignedThis
(
Id int,
TheDate decimal(17,0) -- this was hard to write with a straight face
);
INSERT dbo.WhoDesignedThis(Id, TheDate) VALUES
(1, 20210722054500000),
(2, 19991231132247699);
This query:
;WITH x AS
(
SELECT Id, TheDate, x = CONVERT(char(17), TheDate)
FROM dbo.WhoDesignedThis
)
SELECT Id, TheDate, output = DATETIMEFROMPARTS
(
LEFT(x,4),
SUBSTRING(x,5,2),
SUBSTRING(x,7,2),
SUBSTRING(x,9,2),
SUBSTRING(x,11,2),
SUBSTRING(x,13,2),
RIGHT(x,3)
)
FROM x;
Produces these results:
Id
TheDate
output
1
20210722054500000
2021-07-22 05:45:00.000
2
19991231132247699
1999-12-31 13:22:47.700
Example db<>fiddle
from the beginning. I extracted data from Sap to MYSQL DB. In some tables, there are columns that were extracted as FLOAT and looks like this: 20131009012152.
As you can see it's like the string but float.
If I try to convert it into datetime, I get errors or overload etc.
I have tried CAST, CONVERT, SRT, SUBSTRING, nothing works.
Last try:
SELECT top 10 CREATED_AT,
SUBSTRING(CAST(STR(CREATED_AT, 25, 5) as varchar), 1, 4)
from databank.tablename;
-- wanted to substract parts (here, year) but I get just empty column as result.
Cast to nvarchar to datetime doesn't work. as well as nvarchar- bigint - datetime.
Hope, somebody can help me, thanks
One option, rather ugly, uses the CONVERT function with a series of string concatenations. I first get your numeric timestamp over to a string using a CTE.
WITH cte AS (
SELECT CAST(20131009012152 AS VARCHAR) num
)
SELECT
CONVERT(datetime, SUBSTRING(num, 1, 4) + '-' + SUBSTRING(num, 5, 2) + '-' +
SUBSTRING(num, 7, 2) + ' ' + SUBSTRING(num, 9, 2) + ':' +
SUBSTRING(num, 11, 2) + ':' + SUBSTRING(num, 13, 2), 120) AS the_date
FROM cte;
The verbosity of this query and your data makes me think that you probably did not export properly. Use this only if SAP really has no ability to export a proper timestamp (which I doubt).
Output:
09.10.2013 01:21:52
Demo
Found the similar way that can be directly used in SELECT:
CONVERT(datetime,
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 1,5) + '-' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar),6, 2) + '-' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 8, 2) + ' ' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar),10, 2) + ':' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 12, 2) + ':' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 14, 2), 120) as [COLUMN]
Result: 2017-01-01 15:33:15.000
Besides an old threat I want to share my solution:
Normally the SAP-Timestamps come like this in a char or varchar: 20220620081129
To bring it into a usable SQL format you need to stretch it into a date/datetime
format with dashes and colons.
This can be easily achieved by converting the text into a int/bigint and then
formatting this number into an output format that looks like a date.
Next step is just converting this resulting text into a datetime.
/*Code:*/
convert(datetime,format(convert(bigint,<fieldname>),'##-##-## ##:##:##'),120)
/*Example*/
DECLARE #SAPTable AS TABLE ([/BIC/XCREATE] VARCHAR(30))
INSERT INTO #SAPTable ([/BIC/XCREATE])
VALUES ('20220822144737');
SELECT convert(DATETIME, format(convert(BIGINT, [/BIC/XCREATE]), '##-##-## ##:##:##'), 120)
FROM #SAPTable
As easy as this.
Just adjust the fieldname [/BIC/XCREATE] and the output format to your needs.
In case you have other (shorter or longer) datetime values then, for sure, some things are needed to be adjusted but the principle is the same.
At the end the result is a real date value in terms of the SQL-Server and can be used anyhow.
I think that way it's easier than fiddling with substrings.
My table TRANS contains T_STAMP column with the value '20170721154922' is a YYYYMMDDHHMMSS format. I am trying to write a query to display as MM/DD/YY in one column and HH:MM:SS in another column.
I am trying to convert this with the method CONVERT(VARCHAR(10),GETDATE(),10)
but I need full snippet to execute.
Could you help .
The following query can be return the exact format you required, the date as MM/DD/YY and time as HH:MM:SS:
SELECT CONVERT(VARCHAR(8), CONVERT(DATE, LEFT(T_STAMP, 8)), 1) AS DateValue,
CONVERT(VARCHAR(8), CONVERT(TIME,
SUBSTRING(T_STAMP, 9, 2) + ':'
+ SUBSTRING(T_STAMP, 11, 2) + ':'
+ SUBSTRING(T_STAMP, 13, 2)), 8) AS TimeValue
FROM Trans
Output:
DateValue | TimeValue
-----------|-----------
07/21/17 | 15:49:22
The following query will convert a value from the given format (YYYYMMDDHHMMSS) to DATE and TIME
DECLARE #T_STAMP NVARCHAR(100)='20170721154922'
SELECT CONVERT(DATE,LEFT(#T_STAMP,8)) T_DATE
,CONVERT(TIME,SUBSTRING(#T_STAMP,9,2)+':'
+SUBSTRING(#T_STAMP,11,2)+':'
+SUBSTRING(#T_STAMP,13,2)) T_TIME
As you mentioned the values are stored in YYYYMMDDHHMMSS format, so hope the values always be in fixed length (length 14).
Note:- As commented by Jens, Storing timestamps as formated strings is no good idea. Better store it in a timestamp datatype.
SELECT FORMAT(GETDATE() , 'MM/dd/yyyy HH:mm:ss')
the above would return something like this(21/07/2017 16:02:20).
select date_format(str_to_date('20170721154922', '%Y%m%d%H%S'), '%m%d%y');
'20170721154922' is a very very bad format to store date...
DECLARE #d varchar(14) = '20170721154922';
DECLARE #date DATETIME = CONVERT(datetime2, LEFT(#d, 8), 112);
DECLARE #time DATETIME = CONVERT(datetime2, CONCAT(SUBSTRING(#d, 9, 2), ':', SUBSTRING(#d, 11, 2), ':', SUBSTRING(#d, 13, 2)), 108);
SELECT FORMAT(#date, 'MM/dd/yy') date, FORMAT(#time, 'HH:mm:ss') time
My SQL Server system is 2016.
As topic, I want to convert YYYYMMDD-HHMMSS to mm/dd/yyyy hh:mm:ss, and use dynamic SQL to fulfill this.
My data looks like this:
ID
20161119-075950
20161117-110952
20161118-153406
The datatype is nvarchar.
While I used the syntax below:
SELECT convert(date,convert(varchar(max),id,130), 130) from abc
An error Conversion failed when converting date and/or time from character string. shows up. I am thinking whether it is because SQL Server cannot identify this YYYYMMDD-HHMMSS as date type, and I need to convert this to YYYYMMDD hh:mm:ss first and then mm/dd/yyyy hh:mm:ss? Feel free to shed some lights. Thanks!
Select CONVERT(VARCHAR(25) , CAST(LEFT(ID , 8) AS DATETIME), 101)
+ ' ' + LEFT(RIGHT(ID , 6) ,2) + ':'
+ SUBSTRING(RIGHT(ID , 6) , 3,2) + ':'
+ RIGHT(ID , 2)
FROM TableName
Try it like this
DECLARE #tbl TABLE(ID NVARCHAR(100));
INSERT INTO #tbl VALUES
('20161119-075950')
,('20161117-110952')
,('20161118-153406');
--This is the actual select you need:
SELECT CAST(LEFT(ID,8) AS DATETIME) + STUFF(STUFF(RIGHT(ID,6),5,0,':'),3,0,':')
FROM #tbl
Your first part is strictly 8 chars long and implicitly casteable (unseperated datetime yyyymmdd). The time part is strictly 6 chars long. I use STUFF to insert the colons. This time can be added to a DATETIME. It will be - again implicitly - casted to DATETIME.
EDIT
To reach the given format you stated in the title just convert the first part first with code 101:
SELECT CONVERT(VARCHAR(10),CAST(LEFT(ID,8) AS DATETIME),101) + ' ' + STUFF(STUFF(RIGHT(ID,6),5,0,':'),3,0,':')
FROM #tbl
This should get the format you want... but there are probably better ways.
select
convert(varchar(16),convert(date,left(ID,8)),101) +
' ' +
substring(substring(ID,10,6),1,2) +
':' +
substring(substring(ID,10,6),3,2) +
':' + substring(substring(ID,10,6),5,2)
I have a table that stores an int for month and year. I need to convert that to a date (we can use the first day of the month and the day).
I tried something like below but got an error about converting int to date
AND CAST(ym.year + '-' + ym.month + '-' + '01' AS DATE) BETWEEN #startDate AND #endDate
End result should be be something like 2016-05-01 so I can check the date against a start and end date that I pass to the function.
You could try something like this, modified for your use:
declare #YY int = 2016
declare #MM int = 5
select CAST(CAST(#YY as varchar(4)) + '-' + RIGHT('00' + CAST(#MM as varchar(2)),2) + '-01' as DATE)
From SQL Server 2012 on you can use DATEFROMPARTS
AND DATEFROMPARTS(ym.year, ym.month, 1) BETWEEN #startDate AND #endDate
AND DateFromParts(ym.year, ym.month, 1) BETWEEN #startDate AND #endDate
EDIT: For old versions of SQL:
SELECT CAST(CAST(ym.year*10000+ym.month*100+1 AS CHAR(8)) AS DATETIME)
Try this :
CAST(CAST(ym.year AS varchar) + '-' + CAST(ym.month AS varchar) + '-01' AS DATETIME)
This will work if you are on 2008 or lower
select cast(
cast(ym.year as varchar(4))+
case when len(ym.month) < 2 then '0' + cast(ym.month as varchar(2)) else cast(ym.month as varchar(2)) end +
'01' as date)
The Error you are getting is because when you CONCAT your INT values there is no leading 0 for days before 10, or months before October, thus your CAST to DATE is essentially missing values to do the conversion. Here we are padding based off the length.
You could go the data way and create a table of year, month and date as first of month then join the tables. this may be faster for a large table especially if the number of years and months in the original table is limited.
So if you have a years data in your original table there would only be 12 records required, which as a join added into your processing should be quick.
To avoid missing dates, build the lookup table from original data:
SELECT year, month, cast(cast(year*10000+month*100+1 as char(8)) as date) as FirstOfMonth
INTO #FirstOfMonth FROM mytable GROUP BY year, month