I have the above table and I want to create a DATETIME value from it.
I've tried a number of ways using CONCAT, CONVERT and CAST to glue these together in a way that produces a datetime value and can't get there. I can produce a string that will convert like this.
CONCAT(
'''',
Year,
'-',
CASE LEN(Month) WHEN 1 THEN CONCAT('0', LTRIM(RTRIM(STR(Month)))) ELSE CAST(Month AS VARCHAR(2)) END,
'-',
CASE LEN(Day) WHEN 1 THEN CONCAT('0', LTRIM(RTRIM(STR(Day)))) ELSE CAST(Day AS VARCHAR(2)) END,
' ',
Hour,
':00:00.000',
''''
)
However, I wrap that output in a call to cast or convert it fails.
Can someone point me in the right direction?
Select Cast(Convert(nvarchar,[year])+'-'+Convert(nvarchar,[month])+'-'+Convert(nvarchar,[day])+' '+Convert(nvarchar,[hour])+':00:00.00' as datetime) from [YOUR TABLE]
Related
To avoid any conversion error, we'd like to validate if the target string can be converted to datetime using isdate formula, as follows.
CASE WHEN isdate(#targetstring)= 1 then cast(#targetstring as datetime) else '1900-01-01 00:00:00' end
It's working as expected, it returns 1 when it can be convertible.
select isdate('2021-06-22 23:27:00')
select isdate('20210622')
select isdate('20210622 23:00:00')
But yyyymmddhhmmss can't work as expected, it returns 0, even though the string can be converted to datetime.
select isdate('20210622230000')
If we use this, it seems to work.
select isdate(left('20210622230000', 8) + ' ' + substring('20210622230000', 9,2) + ':' + substring('20210622230000', 11,2) + ':' + substring('20210622230000', 13,2))
If there are any better idea, kindly let me know. Thank you.
Just saying you could trim down string manipulation using STUFF()
Example
Declare #S varchar(50)='20210622232715'
Select try_convert(datetime,stuff(stuff(stuff(#S,13,0,':'),11,0,':'),9,0,' '))
Results
2021-06-22 23:27:15.000
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)
So basically to explain my situation I have a program where a user can select code numbers, that are alpha numeric. These codes are stored in my SQL database as datatype char.
When they select all the codes they want, the program then sends a few parameters(the codes being one of them). The codes are strung together and look something like this:
',01,1,A3' etc. etc. with commas separating the codes. I have the comma in front, but changing the comma to the back does not change anything.
the #reasonCode variable is the reason codes strung together.
In my where clause I have a statement that is this:
(#reasonCode = 'ALL') OR
((#reasonCode <> 'ALL' AND (charindex(',' + ro_reason_code, #reasonCode) > 0)))
Basically I want to restrict my results to just those that have those specific reason codes the user selected(among other parameters). I am trying to achieve that by stringing together the codes, and then searching through them using charindex, seperated by commas.
However I am running into an issue. Here are the results using a few different variations of reason codes:
',1' = 625 records (correct number)
',01' = 1015(correct number)
',01,1 = 1640(correct number)
',1,01' = 1015(for whatever reason it isn't picking up the 1 reason codes)
That is my issue right there.
When I put the 1 in front of the 01, it doesn't pick up the 1 reason codes. But if I do it flip-flopped it works fine...
Any ideas as to why this happens?
(I have tried also using the concat function and get the same results, and also tried forcing everything to be char datatype.)
In the end I would like the same result, regardless if it is ,01,1 or ,1,01.
I'm pretty sure this is because you said you're using the char type instead of varchar. Try replacing your charindex expression with this:
charindex(',' + rtrim(ro_reason_code), #reasonCode)
When I used a type of char(2) in the table and char(16) for the #reasonCode, I could reproduce your result, and I found that adding the rtrim fixed the problem. But unfortunately I can't explain exactly what's going here, why having ',1' at the end of the string should work without the trim whereas having it at the beginning does not. Hopefully someone can provide a more in-depth answer that gets into the "why," but I thought I'd still post this for the time being to get you running.
Reproduction:
-- Forgive the "hackish" way of populating this table. I'm assuming sysobjects has >=1015 records.
declare #Code table (ro_reason_code char(2));
insert #Code select top 625 '1' from sysobjects;
insert #Code select top 1015 '01' from sysobjects;
declare #reasonCode char(16);
set #reasonCode = ',1,01';
select count(1) from #Code where #reasonCode = 'ALL' or charindex(',' + ro_reason_code, #reasonCode) > 0; -- Result: 1015
select count(1) from #Code where #reasonCode = 'ALL' or charindex(',' + rtrim(ro_reason_code), #reasonCode) > 0; -- Result: 1640
set #reasonCode = ',01,1';
select count(1) from #Code where #reasonCode = 'ALL' or charindex(',' + ro_reason_code, #reasonCode) > 0; -- Result: 1640
select count(1) from #Code where #reasonCode = 'ALL' or charindex(',' + rtrim(ro_reason_code), #reasonCode) > 0; -- Result: 1640
Because you are using char, which is a fixed length field, your data is stored padded out to the length of the field. So '1' is stored as '1 '
DECLARE #Code CHAR(2)
SET #Code = '1'
SELECT '''' + #Code + ''''
-- Printes '1 '
For that reason, when you add ',' to the value, you now have ',1 ' (notice the trailing whitespace)
DECLARE #Code CHAR(2)
SET #Code = '1'
SELECT '''' + ',' + #Code + ''''
-- prints ',1 '
Now if you're comparing off another char field, there will also be padded whitespace if the character data is less than the length of the field. So what appers to be ',11,1' is actually something like ',11,1 ' which does match the pattern of ',1 '
BUT, when you reverse the order, ',1,11' becomes ',1,11 ' which does not match the pattern of ',1 '
Unrelated
I just want to point out there is a subtle issue with the implementation. By only appending the leading comma, you may get false positives depending on your data. For example, ,2 will match the pattern ,25.
,2 does match 1,11,25,A01
You've gotta append the comma on both sides of each side of the evaluation.
CHARINDEX( ',' + RTRIM(ro_reason_code) + ',',
',' + RTRIM(#reasonCode) + ',') > 0
So to illustrate the difference it becomes
,2, does not match ,1,11,25,A01,
With SQL-server 2008 database I have a char(14) data type that I want to convert to a datetime.
Example char(14) values:
20120209102026
20010131120000
The date format is yyyymmdd of some sort.
It seems like the values I posted are not the only format, because I get an "index out of range" error for some of the values. For this I can skip the ones that are not valid dates.
declare #c char(14)
select #c='20120209102026'
Select Cast(Substring(#c,1,8) + ' ' + Substring(#c,9,2)+':'+
Substring(#c,11,2)+':'+ Substring(#c,13,2) as DateTime)
Second Version that ignores out of range numeric values:
Select Cast(
Rtrim(Substring(#c,1,8)
+ Case When len(Substring(#c,9,4))>=4 then +' '+ Substring(#c,9,2) else '' end
+ Case When len(Substring(#c,11,2))=2 then +':'+ Substring(#c,11,2) else '' end
+ Case When len(Substring(#c,13,2))=2 then +':'+ Substring(#c,13,2) else '' end)
as Datetime)
This is ugly but if your format is yyyymmddhhmmss then you can use:
select cast(left(yourDate, 8)+' '+
SUBSTRING(yourDate, 9, 2)+':'+SUBSTRING(yourDate, 11, 2)+':'+RIGHT(yourDate, 2) as datetime)
from yourtable
See SQL Fiddle with Demo
A series of function calls but ends up with the same outcome.
Try like this:
select convert(datetime,STUFF(STUFF(STUFF(STUFF(STUFF('20010131120000',5,0,'/'),8,0,'/'),11,0,' '),14,0,':'),17,0,':'))
Look here for how STUFF works!
I have a decimal column in a table defined as decimal(8,3). I would like to include this column in a Select statement, convert it to a Varchar and only display two decimal places. I can't seem to find the right combination of options to do this because everything I try still produces three decimal places.
Here's one way:
create table #work
(
something decimal(8,3) not null
)
insert #work values ( 0 )
insert #work values ( 12345.6789 )
insert #work values ( 3.1415926 )
insert #work values ( 45 )
insert #work values ( 9876.123456 )
insert #work values ( -12.5678 )
select convert(varchar,convert(decimal(8,2),something))
from #work
if you want it right-aligned, something like this should do you:
select str(something,8,2) from #work
If you are using SQL Server 2012, 2014 or newer, use the Format Function instead:
select Format( decimalColumnName ,'FormatString','en-US' )
Review the Microsoft topic and .NET format syntax for how to define the format string.
An example for this question would be:
select Format( MyDecimalColumn ,'N','en-US' )
You might need to convert the decimal to money (or decimal(8,2)) to get that exact formatting. The convert method can take a third parameter that controls the formatting style:
convert(varchar, cast(price as money)) 12345.67
convert(varchar, cast(price as money), 0) 12345.67
convert(varchar, cast(price as money), 1) 12,345.67
I think CAST(ROUND(yourColumn,2) as varchar) should do the job.
But why do you want to do this presentational formatting in T-SQL?
Hope this will help you
Cast(columnName as Numeric(10,2))
or
Cast(#s as decimal(10,2))
I am not getting why you want to cast to varchar?.If you cast to varchar again convert back to decimail for two decimal points
Hope this will help .
DECLARE #emp_cond nvarchar(Max) =' ',#LOCATION_ID NUMERIC(18,0)
SET#LOCATION_ID=10110000000
IF CAST(#LOCATION_ID AS VARCHAR(18))<>' '
BEGIN
SELECT #emp_cond= #emp_cond + N' AND
CM.STATIC_EMP_INFO.EMP_ID = ' ' '+ CAST(#LOCATION_ID AS VARCHAR(18)) +' ' ' '
END
print #emp_cond
EXEC( #emp_cond)
If the type is decimal(18,0) you need to do a double convert like so:
convert(varchar, convert(decimal, [Bill to Account Number] ))
Otherwise, if you just do convert(varchar) you will get scientific notation.