December 13, 2005 at 10:36 am
select convert(smalldatetime, (convert(varchar(10), dateField, 101))) as dateField
from dbo.TableA
December 13, 2005 at 11:24 am
No thats basically it.
If you find yourself using that alot, you can certainly create a user defined function. and call it, instead of typing the convert statement a bunch of times.
December 13, 2005 at 3:18 pm
Actually, that's not the most efficient way. For a smalldatetime, it is stored internally as two 2-byte integers.
You can convert a date to a float, Floor() it to get the 2 bytes that represent the date, then convert that back to a smalldatetime to get the date without time:
Declare @test-2 As SmallDateTime
Select @test-2 = '13 Dec 2005 13:51'
Select convert(smalldatetime, floor(convert (float, @test-2 )))
This saves the string-parsing required to extract date parts from a Varchar(10) allowing for locale & date format etc.
Adding to that, if the expression is being used to filter records, and if the smalldatetime column is indexed, the use of the expression with prevent indexes from being used. Try this example, and run query showplan on the 2 selects. 1 will tablescan, 1 will use an index seek. Huge performance difference if this is a large data set.
-- Test temp table
create table #test
(
DataColumn varchar(50) not null,
DateTimeStamp smalldatetime not null
)
-- Create some test data over a 5 day period
Insert Into #test (DataColumn, DateTimeStamp) values ('blah blah', DateAdd(d, -4, getdate()) )
Insert Into #test (DataColumn, DateTimeStamp) values ('blah blah2', DateAdd(d, -3, getdate()) )
Insert Into #test (DataColumn, DateTimeStamp) values ('blah blah3', DateAdd(d, -2, getdate()) )
Insert Into #test (DataColumn, DateTimeStamp) values ('blah blah4', DateAdd(d, -1, getdate()) )
Insert Into #test (DataColumn, DateTimeStamp) values ('blah blah5', getdate() )
--Index the smalldatetime column
Create Unique Index #ixTestDateTime on #test(DateTimeStamp)
-- Filter records using an expression to remove time portion
Select * from #test
Where convert(smalldatetime, (convert(varchar(10), DateTimeStamp, 101))) = '13 Dec 2005'
-- Filter records by date range to avoid the expression
Select * from #test
Where DateTimeStamp >= '13 Dec 2005' And DateTimeStamp < '14 Dec 2005'
December 14, 2005 at 3:04 am
There are several threads discussing this subject and I think the concensus is that the following are the most efficient to avoid the use of CONVERT.
CAST(DATEADD(day,DATEDIFF(day,0,@dateField),0) as smalldatetime)
CAST(CAST(@dateField as int) as smalldatetime)
But as PW has stated, this will not help if you are matching against an indexed column. I do as shown in PW's last query but using variables, eg
DECLARE @FromDate smalldatetime,@ToDate smalldatetime
SET @FromDate = '20051213'
SET @ToDate = DATEADD(day,1,@FromDate)
SELECT DateTimeStamp
FROM
WHERE DateTimeStamp >= @FromDate
AND DateTimeStamp <= @ToDate
Far away is close at hand in the images of elsewhere.
Anon.
December 14, 2005 at 10:04 am
USE the CAST function
select
SQLServerName = substring(a.Name,1,20)
,' date' = CAST ( a.createdate as varchar(11))
From dbo.table1 a
,dbo.table2 s
where s.Name = a.Name
group by substring(a.Name,1,20),CAST ( a.createdt as varchar(11))
Thanks,
-Nirmal
SQL Server DBA /Oracle DBA
December 16, 2005 at 3:56 am
hey
you can try this way its easy know..
Select convert (varchar, getdate(),101)
regards
balram
December 16, 2005 at 4:48 am
Just for giggles. You can also use the internal storage format of a SMALLDATETIME to get rid of the TIME portion.
DECLARE @dt SMALLDATETIME
SET @dt = CAST(GETDATE() AS SMALLDATETIME)
SELECT
CAST(CAST(SUBSTRING(CAST(@dt AS BINARY(4)),1,2) AS INT) AS SMALLDATETIME)
Though it doesn't look that intuitive, it seems to be even slightly faster than the DATEADD(DATEDIFF()) approach in most scenarios.
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
December 16, 2005 at 2:20 pm
Try this
SELECT DATEADD(day, DATEDIFF(day, 0, getdate()), 0)
You can make it into UDF
---------------------------------------------
[font="Verdana"]Nothing is impossible.
It is just a matter of time and money.[/font]
December 16, 2005 at 6:55 pm
I ran a quick benchmark and included Sergiy's solution to this problem.
Sergiy.......... CAST( CAST( ( MyTs - 0.5 ) as integer ) as smalldatetime )
PW............... convert(smalldatetime, floor(convert (float, MyTs )))
David Burrows... CAST(DATEADD(day,DATEDIFF(day,0,@dateField),0) as smalldatetime)
Frank Kalis..... CAST(CAST(SUBSTRING(CAST(MyTs AS BINARY(4)),1,2) AS INT) AS SMALLDATETIME)
Benmark based on running 8,640 on a Pentium 400:
...............CPU Ms....Elapsed
Sergiy..............279......279
PW...................311......372
David Burrows..301......307
Frank Kalis.......309......309
AND THE WINNER IS Sergiy !!
SQL = Scarcely Qualifies as a Language
December 16, 2005 at 9:06 pm
LOL .. so I wasn't the only 1 having a slow Friday at work. I did some benchmarking too and came to the conclusion that ... I'd learned something new. Thanks guys, so many ways to skin a cat, some of which performed better and which I'd never seen before.
December 19, 2005 at 5:30 am
Sergiy.......... CAST( CAST( ( MyTs - 0.5 ) as integer ) as smalldatetime )
PW............... convert(smalldatetime, floor(convert (float, MyTs )))
David Burrows... CAST(DATEADD(day,DATEDIFF(day,0,@dateField),0) as smalldatetime)
Frank Kalis..... CAST(CAST(SUBSTRING(CAST(MyTs AS BINARY(4)),1,2) AS INT) AS SMALLDATETIME)
Benmark based on running 8,640 on a Pentium 400:
...............CPU Ms....Elapsed
Sergiy..............279......279
PW...................311......372
David Burrows..301......307
Frank Kalis.......309......309
AND THE WINNER IS Sergiy !!
Carl, how does this SELECT CAST(DATEDIFF(DAY,0,GETDATE()) AS SMALLDATETIME) perform in your test?
I'm guessing that it's among the top performers. However, would you ever use such a construct in the WHERE clause of a query? Certainly not, or?
The only drawback with Sergiy's and PW's solution I see is, that a conversion from DATETIME to FLOAT and back again is not explicitely mentioned in BOL, AFAIK. In Microsoft terms this usually means that it is an unofficial and therefore unsupported solution. And as such potentially subject to change anytime.
Anyway, there is definitely more than one way to skin that cat. And which one performs "best" in a given scenario is, as always, to be tested.
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
December 19, 2005 at 12:35 pm
"However, would you ever use such a construct in the WHERE clause of a query?"
I would hope not, as this would preclude the use of an index.
For the WHERE, bettter to use the between with the end date being the start date plus 1 day and then minus 3 milliseconds.
A "date only" algorithm would be useful in a check constraint to insure that the time is always midnight and also useful in a group by to aggregate by date.
SQL = Scarcely Qualifies as a Language
December 20, 2005 at 1:21 am
As I'm being told, MS dropped their announced new DATE data type from SQL Server 2005. What a pity!
Btw, when you are interested - for whatever reason - in the time portion, and you CAST back and forth between DATETIME and FLOAT, your chances are pretty good to produce inaccuracies every now and then
SELECT GETDATE(), CAST(CAST(GETDATE() AS FLOAT) AS DATETIME)
--
Frank Kalis
Microsoft SQL Server MVP
Webmaster: http://www.insidesql.org/blogs
My blog: http://www.insidesql.org/blogs/frankkalis/[/url]
Viewing 13 posts - 1 through 12 (of 12 total)
You must be logged in to reply to this topic. Login to reply