I have two columns in my table, one to capture time and one to capture date. Unfortunately, both are varchar(). I need to take the two fields, concatenate them together, and then convert them to datetime.
I am trying to accomplish that with this:
select CONVERT(datetime,(select txt_returned_date+' '+CONVERT(varchar(20),CONVERT(TIME,txt_time_returned))),126)
from table_name
I am getting this error message:
Conversion failed when converting date and/or time from character string.
The date is being captured as "20130308" as a string. Time is being captures as "4:27 PM" as a string
What I am doing here is converting the string of the time to TIME, then back to varchar. Then I am concatenating them together. This works by itself, but once I introduce the CONVERT(datetime) to the whole query, it is giving me the error.
Any help to try to accomplish this is helpful. Thanks!
You can concatenate the DATE and TIME values together once they have been converted to a DATETIME. Here's a sample to play with that shows concatenating a DATE column and a TIME column that have been stored as VARCHAR:
-- Set up some variables to test with
DECLARE #myTime TIME = GETDATE()
, #myDate DATE = GETDATE()
, #myTimeTxt VARCHAR(16)
, #myDateTxt VARCHAR(10);
-- Initialize your variables
SELECT #myTimeTxt = #myTime
, #myDateTxt = #myDate;
-- Display your separated values
SELECT #myDateTxt, #myTimeTxt;
-- Display your concatenated value
SELECT CAST(#myDateTxt AS DATETIME) + CAST(CAST(#myTimeTxt AS TIME) AS DATETIME);
You can use this option
DECLARE #date date = '20010101',
#time time = '01:01:01'
SELECT CAST(#date AS datetime) + #time
Result:2001-01-01 01:01:01.000
Demo on SQLFiddle
Are you using SQL 2012? If so you may be able to use the datetimedromparts function to achieve this. If not for this specific example, it's always good to know for the future :)
http://technet.microsoft.com/en-gb/library/hh213233.aspx
Related
So I have a query I'm trying to write where there are two columns that will have variable results. One is date and one is time. My query will look like
Select Schedule ID , Job_Name , next_run_date , next_run_time
The values will vary depending on what database I'm running against. For example, [next_run_date] might = 20181014 and [next_run_time] might read 1000 which would be 1am. But if I run it on a different server, it could have a completely different set of values, but just the same format.
I've unsuccessfully tried to convert the columns to date/time format by using
CONVERT(varchar(10),CONVERT(date,[next_run_date],110),110) AS 'Next Run'
And just get 'Explicit conversion from data type int to date is not allowed'
What I'd like it to display is [next_run_date] might = 10-14-2018 and [next_run_time] = 01:00. Just unsure how to convert this correctly. I do not have to write privs to the database. If I read correctly, at least for the date column, I would have to convert from Bigin to Varchar to ToDate, but unclear how to fully write that.
For the time field you can stuff a : in it.
And a FORMAT for the times below 10 AM.
And the date part can be done with 2 casts and a CONVERT or a FORMAT.
The date from an INT to a VARCHAR in the 'mm-dd-yyyy' format:
CONVERT(VARCHAR(10), CAST(CAST([next_run_date] AS VARCHAR(8)) AS DATE), 110)
The time from an INT to a VARCHAR in the 'hh:mi' format:
STUFF(CAST(FORMAT([next_run_time],'000000') AS VARCHAR(4)),3,0,':')
Example snippet:
DECLARE #Table TABLE (next_run_date INT, next_run_time INT);
INSERT INTO #Table (next_run_date, next_run_time) VALUES
(20180901, 13500)
,(20181015, 134200)
;
SELECT
CONVERT(VARCHAR(10), CAST(CAST([next_run_date] AS VARCHAR(8)) AS DATE), 110) AS [Next Run Date],
STUFF(CAST(FORMAT([next_run_time],'000000') AS VARCHAR(4)),3,0,':') AS [Next Run Time]
FROM #Table
Returns:
Next Run Date Next Run Time
------------- -------------
09-01-2018 01:35
10-15-2018 13:42
You need to convert the bigint to a varchar first, then to a date:
CONVERT(date,CONVERT(varchar(10),[next_run_date]),110) AS 'Next Run'
You could also break up the number into parts and craft a date and time.
DECLARE #Date INT=20181014
DECLARE #Time INT=123456
SELECT CONVERT(DATE,
SUBSTRING(CONVERT(VARCHAR(20),#Date),1,4)+'/'+
SUBSTRING(CONVERT(VARCHAR(20),#Date),5,2)+'/'+
SUBSTRING(CONVERT(VARCHAR(20),#Date),7,2)
) AS [Date]
SELECT CONVERT(TIME,
SUBSTRING(CONVERT(VARCHAR(20),#Time),1,LEN(CONVERT(VARCHAR(20),#Time))-4)+':'+
SUBSTRING(CONVERT(VARCHAR(20),#Time),LEN(CONVERT(VARCHAR(20),#Time))-3,2)+':'+
SUBSTRING(CONVERT(VARCHAR(20),#Time),LEN(CONVERT(VARCHAR(20),#Time))-1,2)
) AS [Time]
select convert(datetime, cast(20181014 as varchar), 102)
Note :
CAST is part of the ANSI-SQL specification; whereas, CONVERT is not.
In fact, CONVERT is SQL implementation specific. CONVERT differences
lie in that it accepts an optional style parameter which is used for
formatting.
I am working on a project in which dates and times ar stored as a varchar e.g. "30-11-2017,7:30" first date in dd-mm-yyy format and then time separated with a comma. I am trying to filter on it but it is not working correctly kindly guide me how to filter data on date.
select *
from timetrack
where startDateAndTime >= '30-11-2017,7:30'
In attached image records have been shown. When I apply above query it shows no records
You can easily convert your date to SQL datatype datetime uisng parse function, for example select parse('30-11-2017,7:30' as datetime using 'it-IT').
So, in your case, you can apply this function in where clause, so you can easily apply comparison between dates:
select *
from timetrack
where parse(startDateAndTime as datetime using 'it-IT') >= '2017-11-30 07:30:00.000'
Your format is apparently italian :) But you have to specify your own date in the format convertable to datetime, as I have done in above example.
NOTE: parse is available starting with SQL Management Studio 2012.
Unless you are using ISO date format (yyyy-MM-dd HH:mm:ss or close) applying ordering (which inequalities like greater than or equal use) will not work: the date order is disconnected from the string ordering.
You'll need to parse the date and times into a real date time type and then compare to that (details of this depend on which RDBMS you are using).
If, you want to just filter out the date then you could use convert() function for SQL Server
select *
from timetrack
where startDateAndTime >= convert(date, left(#date, 10), 103)
Else convert it to datetime as follow
select *
from timetrack
where startDateAndTime >= convert(datetime, left(#date, 10)+' ' +
reverse(left(reverse(#date), charindex(',', reverse(#date))-1)), 103)
You need the date in a datetime column, Otherwise you can't filter with your current varchar format of your date.
Without changing the existing columns, this can be achieved by making a computed column and making it persisted to optimize performance.
ALTER TABLE test add CstartDateTime
as convert(datetime, substring(startDateAndTime, 7,4)+ substring(startDateAndTime, 4,2)
+ left(startDateAndTime, 2) +' '+ right(startDateAndTime, 5), 112) persisted
Note: this require all rows in the column contains a valid date with the current format
Firstly, you need to check what is the data that is entered in the 'startDateAndTime' column,then you can convert that varchar into date format
If the data in 'startDateAndTime' column has data like '30-11-2017,07:30', you would then have to convert it into date:
SELECT to_date('30-11-2017,07:30','dd-mm-yyyy,hh:mm') from dual; --check this
--Your query:
SELECT to_date(startDateAndTime ,'dd-mm-yyyy,hh:mm') from timetrack;
In my table I have myDate column of type nvarchar(50).
The result I need is to select this date/time: 07/11/2013 11:22:07
And I need to get 07/11/2013 11:22:07 am from it (add am/pm to the original date&time).
I tried everything but get only the original data without am/pm.
This is an example from my query :
select convert(dateTime,myDate,100) as Date from Info
or
select convert(dateTime,myDate,0) as Date from Info
What am I missing ?
try this !!
declare #date datetime
set #date='07/11/2013 11:22:07'
SELECT cast(convert(varchar(20),substring(convert(nvarchar(20),#date, 9), 0, 21)
+ ' ' + substring(convert(nvarchar(30), #date, 9), 25, 2),105) as datetime)
Your field is a NVARCHAR field so just return it without any conversion. In your query you convert string representation into the DATETIME type and returns it. Your browser software which shows query results convert DateTime value into string representation to show it to you and conversion format depends on this software usually you can change it changing Windows Regional Settings.
You can get AM/PM data using following query
declare #date datetime
select #date= CAST('07/11/2013 11:22:07' AS datetime)
select RIGHT ( CONVERT(VARCHAR,#date,9),2)
I have one column capturedatetime(Char(30)):
2006-04-25T15:50:59.997000 PM
And I want to convert it and load it at other table column which have is in DateTime. either by T-sql or SSIS which ever way.
I have tried with:
select CONVERT(datetime, '2006-04-25T15:50:59.997000 PM', 126)
But it creates an error:
Conversion failed when converting date and/or time from character string
Late update:
In this column I also have other data that is in a completely different format:
29-JAN-10 08.57.41.000000 PM
(1) STOP storing datetime data in string columns! This is nothing, nothing, nothing but trouble.
(2) Why on earth does your column get data in two different string formats that aren't even valid? Why does the string use 24 hour time and have AM/PM suffix? Why use a regional string format and Y2K disaster like 29-JAN-10?
Here is one way, but it's awfully ugly. I highly recommend you fix the SSIS process to give you valid datetime values in the first place, if not as datetimes, at least as valid ISO strings (yyyy-mm-ddThh:mm:ss.nnn):
DECLARE #x TABLE (d CHAR(30));
INSERT #x SELECT '2006-04-25T15:50:59.997000 PM'
UNION ALL SELECT '29-JAN-10 08.57.41.000000 PM';
SET LANGUAGE ENGLISH; -- this is important, else style 6 may not work
SELECT
CASE WHEN d LIKE '__[0-9]%' THEN
CONVERT(DATETIME, LEFT(d, 23))
WHEN d LIKE '[0-9][0-9]-%' THEN
CONVERT(DATETIME, CONVERT(CHAR(8),
CONVERT(DATETIME,REPLACE(LEFT(d,9),' ','-'),6),112)
+ ' ' + REPLACE(SUBSTRING(d,11,8),'.',':')
+ ' ' + RIGHT(RTRIM(d),2))
END
FROM #x;
The conversion for 126 requires no spaces ... I've got it to work like this:
declare #T varchar(50)
declare #dt datetime
set #T = '2006-04-25T15:50:59.997'
set #dt = convert(datetime,#t,126)
select #T, #dt
select convert(datetime,left('2006-04-25T15:50:59.997000 PM',23))
or
select convert(datetime,left(capturedatetime,23))
If you use cast, you do not even need to supply a format. Code snippet below tested on SQL 2012 Developer version.
declare #var_string varchar(50) = '2006-04-25T15:50:59.997';
declare #var_datetime datetime = cast(#var_string as datetime);
select #var_string as my_string, #var_datetime as my_variable;
I have two "date" fields that I need to join on.
The first is a normal datetime in the format yyyy-mm-dd hh:mm:ss
The second is a varchar(8) in the red-headed step child format mmddyyyy
Now this gets painful because there is no easy way to convert to the corresponding type. There is a built-in format that is yyyymmdd but that doesn't match the varchar format.
There are two paths I can see:
declare #normal_date as datetime;
declare #hated_date as varchar(8);
set #normal_date='1974-11-01 00:00:00.000'
set #hated_date='11011974'
--cast to date time with string splits
select #normal_date
where CONVERT(datetime, RIGHT(#hated_date,4)+LEFT(#hated_date,2)+SUBSTRING(#hated_date,3,2))=#normal_date
--convert normal date to ackward format
select #normal_date
where REPLACE(CONVERT(varchar(10),#normal_date,101), '/','')=#hated_date
Which is better? Or is there a better way?
Edited to show costs
--Operator cost (39%)
CONVERT(datetime, RIGHT(#hated_date,4)+LEFT(#hated_date,2)+SUBSTRING(#hated_date,3,2))=#normal_date
--Operator cost (57%)
REPLACE(CONVERT(varchar(10),#normal_date,101), '/','')=#hated_date
--Operator cost (46%)
cast(stuff(stuff(#hated_date, 3,0, '/'),6,0,'/') as datetime)=#normal_date
--Operator cost (47%)
RIGHT(#hated_date, 4) + LEFT(#hated_date, 4)=#normal_date
This is yyyymmdd no?
RIGHT(#hated_date, 4) + LEFT(#hated_date, 4)
So, your script becomes
declare #normal_date as datetime;
declare #hated_date as varchar(8);
set #normal_date='1974-11-01 00:00:00.000'
set #hated_date='11011974'
--SELECT #hated_date = RIGHT(#hated_date, 4) + LEFT(#hated_date, 4))
select 'hurrah' WHERE #normal_date = RIGHT(#hated_date, 4) + LEFT(#hated_date, 4)
Another approach is this:
MONTH(#normal_date)*1000000 + DAY(#normal_date)*10000 + YEAR(#normal_date)
=
CAST(#hated_date AS INT)
one more thing: it is more precise to compare real execution costs than to rely on the optimizer's estimates.
Try this:
select cast(stuff(stuff('11011974', 3,0, '/'),6,0,'/') as datetime)
Update
Suggest you either fix the column to be datetime or add a datetime column to the table and convert the data so that you only have to do this conversion once when the data is entered (and once of course for existing data) This could probaly even be a calculated column. This is NOT something you want to be doing in select statements. If necessary create a dateconversion table with every opossible date in both formates and join to it if the table can't be changed.
You might also want to check to make sure there are no invalid dates in there which is always a possibility with storing dates in a data type other than a datetime one.