Atlanta Custom Software Development 

 
   Search        Code/Page
 

User Login
Email

Password

 

Forgot the Password?
Services
» Web Development
» Maintenance
» Data Integration/BI
» Information Management
Programming
  Database
Automation
OS/Networking
Graphics
Links
Tools
» Regular Expr Tester
» Free Tools

How to form effective date only search condition.

Total Hit ( 1588)

Rate this article:     Poor     Excellent 

 Submit Your Question/Comment about this article

Rating


 


This script shows a technique to perform effective date searches especially when searching on an indexed column.

Click here to copy the following block
CREATE TABLE #Dates (
    DateCol datetime
);
CREATE CLUSTERED INDEX IX_Dates ON #Dates( DateCol );
INSERT INTO #Dates VALUES( '2000-09-26 10:00:18' );
INSERT INTO #Dates VALUES( '2000-09-26 01:00:23' );
INSERT INTO #Dates VALUES( '2000-09-28 18:20:09' );
INSERT INTO #Dates VALUES( '2000-09-28 03:35:58' );
INSERT INTO #Dates VALUES( '2000-10-20 10:00:47' );
INSERT INTO #Dates VALUES( '2000-10-09 11:41:28' );
INSERT INTO #Dates VALUES( '2000-10-02 06:18:01' );
INSERT INTO #Dates VALUES( '2000-10-06 09:33:10' );
INSERT INTO #Dates VALUES( '2000-10-06 12:45:00' );
SELECT * FROM #Dates;
/*
DateCol                        
------------------------------------------------------
2000-09-26 01:00:23.000
2000-09-26 10:00:18.000
2000-09-28 03:35:58.000
2000-09-28 18:20:09.000
2000-10-02 06:18:01.000
2000-10-06 09:33:10.000
2000-10-06 12:45:00.000
2000-10-09 11:41:28.000
2000-10-20 10:00:47.000
*/

GO
/*
    To get all dates between two given values. Observe the cost of both approaches using
    the show estimated plan output. You can notice that the 1st method forms about
    85.46% of the cost ( relative to the batch ) & the 2nd method forms about
    14.54% of the cost ( relative to the batch ).
*/

DECLARE @Start datetime , @End datetime;
SELECT @Start = '2000-09-26' , @End = '2000-10-08';
-- Usual way of doing the search
SELECT * FROM #Dates
WHERE CONVERT( datetime , CONVERT( varchar , DateCol , 112 ) ) BETWEEN @Start And @End;
-- Showplan for the search shows that the index is not used. This is because of the use
-- of the CONVERT function on the indexed column.
/*
StmtText
--------------------------------------------------------------------------------------------------------------------
 |--Filter(WHERE:(Convert(Convert([#Dates].[DateCol]))>=[@Start] AND Convert(Convert([#Dates].[DateCol]))<=[@End]))
    |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[#Dates_____________________________00000000000D].[IX_Dates]))
*/

/*
DateCol
------------------------------------------------------
2000-09-26 01:00:23.000
2000-09-26 10:00:18.000
2000-09-28 03:35:58.000
2000-09-28 18:20:09.000
2000-10-02 06:18:01.000
2000-10-06 09:33:10.000
2000-10-06 12:45:00.000
*/


/*
    The same search can be done efficiently by manipulating the date portions of the
    Start & End Dates to take care of time values in the date column. So the time
    portion of Start & End date should always start from '12:00 AM'. One day is added to
    get the End date & that is used as the limiting range for the search.
    This will ensure that any time values for the boundary dates are automatically included.
*/

SELECT @Start = convert( varchar , @Start , 112 ) ,
    @End = DATEADD( day , 1 , convert( varchar , @End , 112 ) ) ;
SELECT @Start AS SearchStart , @End AS SearchEnd;
/*
SearchStart       SearchEnd
----------------------- ------------------------------------------------------
2000-09-26 00:00:00.000 2000-10-09 00:00:00.000
*/



SELECT * FROM #Dates
WHERE DateCol >= @Start And DateCol < @End;
-- Showplan text indicates that index seek is performed in this case. This method is very
-- efficient on large tables & the overhead is only in setting up the search values appropriately.
/*
StmtText
----------------------------------------------------------------------------------------------
 |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[#Dates_00000000000D].[IX_Dates]),
             SEEK:([#Dates].[DateCol] >= [@Start] AND
                [#Dates].[DateCol] < [@End]) ORDERED FORWARD)
*/

/*
DateCol
------------------------------------------------------
2000-09-26 01:00:23.000
2000-09-26 10:00:18.000
2000-09-28 03:35:58.000
2000-09-28 18:20:09.000
2000-10-02 06:18:01.000
2000-10-06 09:33:10.000
2000-10-06 12:45:00.000
*/

GO
DROP TABLE #Dates;
GO


Submitted By : Nayan Patel  (Member Since : 5/26/2004 12:23:06 PM)

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.
View all (893) submissions by this author  (Birth Date : 7/14/1981 )


Home   |  Comment   |  Contact Us   |  Privacy Policy   |  Terms & Conditions   |  BlogsZappySys

© 2008 BinaryWorld LLC. All rights reserved.