views:

4517

answers:

6

In an extract I am dealing with, I have 2 fields. One field stores the dates and another the times as shown.

How can I query the table to combine these two fields into 1 column of type date?

Dates

2009-03-12 00:00:00.000
2009-03-26 00:00:00.000
2009-03-26 00:00:00.000

Times

1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
+1  A: 
DECLARE @Dates table ([Date] datetime);
DECLARE @Times table ([Time] datetime);

INSERT INTO @Dates VALUES('2009-03-12 00:00:00.000');
INSERT INTO @Dates VALUES('2009-03-26 00:00:00.000');
INSERT INTO @Dates VALUES('2009-03-30 00:00:00.000');

INSERT INTO @Times VALUES('1899-12-30 12:30:00.000');
INSERT INTO @Times VALUES('1899-12-30 10:00:00.000');
INSERT INTO @Times VALUES('1899-12-30 10:00:00.000');

WITH Dates (ID, [Date])
AS (
    SELECT ROW_NUMBER() OVER (ORDER BY [Date]), [Date] FROM @Dates
), Times (ID, [Time])
AS (
    SELECT ROW_NUMBER() OVER (ORDER BY [Time]), [Time] FROM @Times
)
SELECT Dates.[Date] + Times.[Time] FROM Dates
    JOIN Times ON Times.ID = Dates.ID

Prints:

2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
Koistya Navin
+9  A: 

If the time element of your date column and the date element of your time column are both zero then Lieven's answer is what you need. If you can't guarantee that will always be the case then it becomes slightly more complicated.

If you're using SQL Server 2008 then you can combine the columns like this:

SELECT CAST(CAST(your_date_column AS DATE) AS DATETIME) +
    CAST(your_time_column AS TIME)
FROM your_table

For earlier versions of SQL Server then this is what you'll need:

SELECT DATEADD(day, 0, DATEDIFF(day, 0, your_date_column)) +
    DATEADD(day, 0 - DATEDIFF(day, 0, your_time_column), your_time_column)
FROM your_table
LukeH
Thanks for the answer Luke. Luckily, in this case I can guarantee other items are always zero, I think the 2 fields may even be 1 on the other side the 3rd party code which does the extract for us.
Jon Winstanley
I had the same problem as the OP except I know the unneeded parts are never zero. This has therefore been immeasurably useful, if I could vote you up twice I would!
+12  A: 

You can simply add the two.

  • If the Time part of the Date is always zero
  • and if the Date part of the Time is also always zero (1899-12-30)

Adding the two gives you a correct result.

SELECT Combined = MyDate + MyTime FROM MyTable
Lieven
Surely this can't be true!
Jon Winstanley
Ya-tah! It does!
Jon Winstanley
@Jon, It's true so long as the time element of the date column and the date element of the time column are both zero.
LukeH
Accepted answer due to Occam’s Razor! http://en.wikipedia.org/wiki/Occam's_razor
Jon Winstanley
@Jon - One of those "duh" moments (How I wish I never had them)
Lieven
it does this due to the way the date is stored as a float, with the left part being the date and the right of the decimal being the time, so its like doing 1.0 + 0.5 = 1.5
dnolan
I do this and my date is off (early) by 2 days, but the time is correct?
CodeGrue
Lieven
+2  A: 

If you're not using SQL Server 2008 (i.e. you only have a DateTime data type), you can use the following (admittedly rough and ready) TSQL to achieve what you want:

DECLARE @DateOnly AS datetime
DECLARE @TimeOnly AS datetime 

SET @DateOnly = '07 aug 2009 00:00:00'
SET @TimeOnly = '01 jan 1899 10:11:23'


-- Gives Date Only.
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @DateOnly))

-- Gives Time Only.
SELECT DATEADD(Day, -DATEDIFF(Day, 0, @TimeOnly), @TimeOnly)

-- Concatenates Date and Time parts.
SELECT
CAST(
 DATEADD(dd, 0, DATEDIFF(dd, 0, @DateOnly)) + ' ' +
 DATEADD(Day, -DATEDIFF(Day, 0, @TimeOnly), @TimeOnly)   
as datetime)

It's rough and ready, but it works!

CraigTP
A: 

Convert the first date stored in a datetime field to a string, then convert the time stored in a datetime field to string, append the two and convert back to a datetime field all using known conversion formats.

Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103) 
SPE109
A: 
  1. If both of your fields are datetime then simply adding those will work.

    eg:

    Declare @d datetime, @t datetime
    set @d = '2009-03-12 00:00:00.000';
    set @t = '1899-12-30 12:30:00.000';
    select @d + @t
    
  2. If you used Date & Time datatype then just cast the time to datetime

    eg:

    Declare @d date, @t time
    set @d = '2009-03-12';
    set @t = '12:30:00.000';
    select @d + cast(@t as datetime)
    
Pramod Pallath Vasudevan