Truncating Date

  • Why shoulkd you want to remove the time?

    Typically because you have been passed a datetime but want to select data for a range of complete days.

  • The stored procedure inserts into multiple tables. One of the tables needs only the date as it checks if a record with that date exists (and other fields) and updates if it does and inserts when it does not. There are numerous reports that use this table based on the date only.

    So the query is:

    IF exists (select id from table where theDate = @theDate and otherField=@otherField...)

      UPDATE table SET someOtherField = @someOtherField where theDate = @theDate and otherField=@otherFIeld

    ELSE

       INSERT INTO table (...)

    Now, if there is time in there, I would have to do datepart on check if exists and update.

    There are about 100K records written daily to that table, so it is quite large and then some reports aggregate on the dates.

  • Does anyone have a method for returning the time value of the datetime field?  I have been doing this with a character conversion:

    set @loop = 1

    set @dStart = getdate()

    --uses convert

    while @loop <@lMax

    begin

     set @d= '12/30/1899 ' + Convert(char(12), getdate(), 108)

     set @loop = @loop + 1

    end

    print 'Time Conversion - varchar'

    select datediff(ms, @dStart,getdate()), @d

    This returns only the time portion of the date.  Playing around with the float method I come up with:

    set @loop = 1

    set @dStart = getdate()

    --uses convert

    while @loop <@lMax

    begin

     set @d= cast(cast(getdate() as float)-(floor(cast(getdate() as float)+2)) as datetime)

     set @loop = @loop + 1

    end

    print 'Time Conversion - float'

    select datediff(ms, @dStart,getdate()), @d

     

    This is not the prettiest code but it runs faster than the varchar method.  I am not sure how I could apply the dateadd/datediff method in a way that would return just the time.

     

    Thoughts?

  • You can use dateadd/datepart to calculate # of seconds in a day and add that to 0 date.

    The below example would return: 1900-01-01 18:01:06.000

    declare @x dateTime

    set @x = '2006-4-13 18:01:06'

    select dateadd(second, datepart(hour, @x)*3600+datepart(minute, @x)*60+datepart(second, @x), 0)

     

    If you need ms accuracy you would have to mult. all those by additional 1000 add datepart(ms,@x) and dateadd(ms...)

     

  • wjwGeorgia,

    You can take a look at http://vyaskn.tripod.com/searching_date_time_values.htm

  • I just can't bring myself to trust anything in an article where the author makes mistakes like the following...

    "Remember that the BETWEEN clause retrieves values that are equal to the upper and lower limits, so you can’t code the upper limit as just '2002-02-29'. If you do, then you’ll incorrectly retrieve row 3. Another way to get the same result is to use comparison operators:

    SELECT * FROM DateSample

    WHERE DateVal >= '2002-02-28' AND DateVal < '2002-02-29'"

    And, it's obvious author didn't test the code or he/she would have gotten the following error...

    Server: Msg 242, Level 16, State 3, Line 1

    The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Although the DATEADD/DATEDIFF method will sometimes return a faster duration, it is slower than "convert(datetime,convert(int,GetDate()-.5))" if you consider actual resources used like CPU Seconds and DIsk Reads and Writes.  Here's the results from my million row test table on a single processor box...

    Method:

    CONVERT/VARCHAR

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    5733

    5750

    5733

    5739

    5623

    5610

    5576

    5603

    CPU Usage (ms)

    5641

    5672

    5719

    5677

    5500

    5485

    5454

    5480

    Disk Reads/Writes

    378

    378

    378

    378

    113

    113

    113

    113

    Method:

    CAST/FLOOR

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    2016

    2000

    2016

    2011

    2060

    1970

    2050

    2027

    CPU Usage (ms)

    1984

    1968

    1938

    1963

    1782

    1813

    1813

    1803

    Disk Reads/Writes

    378

    378

    378

    378

    113

    113

    113

    113

    Method:

    DATEADD/DATEDIFF

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    1796

    1843

    1936

    1858

    1030

    1096

    1080

    1069

    CPU Usage (ms)

    859

    828

    922

    870

    796

    844

    813

    818

    Disk Reads/Writes

    379

    379

    379

    379

    113

    113

    113

    113

    Method:

    CONVERT/INT

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    1830

    1860

    1843

    1844

    950

    920

    953

    941

    CPU Usage (ms)

    703

    734

    609

    682

    703

    657

    704

    688

    Disk Reads/Writes

    378

    378

    378

    378

    113

    113

    113

    113

    Method:

    CALCULATED COL

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    1826

    1856

    1826

    1836

    1813

    1810

    1796

    1806

    CPU Usage (ms)

    1046

    1109

    1000

    1052

    969

    890

    907

    922

    Disk Reads/Writes

    378

    378

    378

    378

    378

    378

    378

    378

    Method:

    FUNCTION

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    9110

    9236

    9186

    9177

    8840

    8813

    8826

    8826

    CPU Usage (ms)

    8953

    9031

    9047

    9010

    8719

    8703

    8750

    8724

    Disk Reads/Writes

    386

    386

    386

    386

    121

    121

    121

    121

    Both sets of test had a Primary Key on an unrelated column. (Sorry for the messy display... HTML does weird things to a spreadsheet.

    Here's the results on a multi-processor box with a SAN attached...

    Method:

    CONVERT/VARCHAR

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    4376

    4500

    4500

    4459

    3250

    3286

    3296

    3277

    CPU Usage (ms)

    3454

    3360

    3297

    3370

    3188

    3250

    3250

    3229

    Disk Reads/Writes

    704

    704

    704

    704

    124

    124

    124

    124

    Method:

    CAST/FLOOR

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    3920

    3940

    4016

    3959

    1093

    1063

    1063

    1073

    CPU Usage (ms)

    1140

    1313

    1141

    1198

    1031

    1062

    1031

    1041

    Disk Reads/Writes

    704

    704

    704

    704

    124

    124

    124

    124

    Method:

    DATEADD/DATEDIFF

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    3750

    3810

    3783

    3781

    483

    470

    483

    479

    CPU Usage (ms)

    593

    437

    766

    599

    485

    464

    485

    478

    Disk Reads/Writes

    704

    704

    704

    704

    124

    124

    124

    124

    Method:

    CONVERT/INT

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    3733

    3860

    3720

    3771

    373

    376

    373

    374

    CPU Usage (ms)

    344

    406

    344

    365

    375

    375

    344

    365

    Disk Reads/Writes

    704

    704

    704

    704

    124

    124

    124

    124

    Method:

    CALCULATED COL

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    3796

    3826

    3780

    3801

    4106

    4186

    3906

    4066

    CPU Usage (ms)

    578

    672

    594

    615

    500

    609

    562

    557

    Disk Reads/Writes

    704

    704

    704

    704

    108

    708

    708

    508

    Method:

    FUNCTION

    WITHOUT an Index on "ADate"

    WITH an Index on "ADate"

    Measurement

    Run 1

    Run 2

    Run 3

    Avg

    Run 1

    Run 2

    Run 3

    Avg

    Duration (ms)

    5360

    5343

    5296

    5333

    4733

    4796

    4813

    4781

    CPU Usage (ms)

    4781

    4813

    4688

    4761

    4625

    4703

    4734

    4687

    Disk Reads/Writes

    712

    712

    712

    712

    135

    135

    135

    135

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • It's obvious that author just used not the same DATEFIRST settings on his server as you.

    _____________
    Code for TallyGenerator

  • "It's obvious that author just used not the same DATEFIRST settings on his server as you."

    Actually, the date was specified as '2002-02-29', which is invalid no matter what the regional setting, because 2002 was not a leap year, and thus there is no 29-FEB-2006. (the only other alternate for intrepeting the date is month=29, which is obviously invalid as well).

    The article isn't bad, but the author obviously didn't test the code.

     

  • Author must have used set of values with another year.

    Because he displays the table with value '2002-02-29' in datetime column.

    It's impossible.

    I think originally there was another year in those examples, replaced before publishing for some reason (not to show when the article was originally written?)

    _____________
    Code for TallyGenerator

  • I have a similar problem. I have lots of tables where the time part is getting stored and need to quickly ensure only the date is stored without changing app code.

    Can I add some constraint to the column so it will store only the date part?

  • mathur.akhil (1/22/2009)


    I have a similar problem. I have lots of tables where the time part is getting stored and need to quickly ensure only the date is stored without changing app code.

    Can I add some constraint to the column so it will store only the date part?

    Yeah, you could put a constraint on it... and cause all sorts of heartache in the app. If you could, it would be considered to be a loss of potentially important data.

    As a side bar, this is the reason why stored procedures should be created to retrieve and store data in tables. Had that been done instead of allowing the APP to have direct access to the table data, this would be a no brainer because it would be a minor change to a stored procedure... instead, you need to find EVERYWHERE it is done in the APP, recompile it, retest it, and resdistribute it.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

Viewing 12 posts - 16 through 26 (of 26 total)

You must be logged in to reply to this topic. Login to reply