Need help with sql query

  • I have a table in which date is divided into 3 columns salesyear,salesmonth and salesday.

    Now I need to create a sql select query for a date range say from 1/20/2010 to 2/9/2010.

    I am not sure how to do that.Please help!

  • You'll have to post the DDL and sample data (see first link in my sig for help if needed to make it consumable) for us to help you on this. At first glance, you're going to need to do some form of concatonation of the information into real datetime values, blowing up any chance for avoiding a clustered scan. After that's done, you should be able to use standard practices.


    - Craig Farrell

    Never stop learning, even if it hurts. Ego bruises are practically mandatory as you learn unless you've never risked enough to make a mistake.

    For better assistance in answering your questions[/url] | Forum Netiquette
    For index/tuning help, follow these directions.[/url] |Tally Tables[/url]

    Twitter: @AnyWayDBA

  • Here is the table Structure:-

    CREATE TABLE [dbo].[Test](

    [projCode] [nvarchar](5) NULL,

    [salesMonth] [int] NULL,

    [salesDay] [int] NULL,

    [salesYear] [int] NULL,

    [decalYear] [int] NULL,

    [transactionCount] [bigint] NULL,

    [transactionType] [nvarchar](5) NULL,

    [ExportDate] [datetime] NULL

    ) ON [PRIMARY]

    AND SAMPLE DATA :-

    SELECT '023','1','1','2011','0''0','VR' UNION ALL

    SELECT '023','1','2','2011','0''0','VR' UNION ALL

    SELECT '023','1','3','2011','0''0','VR' UNION ALL

    SELECT '023','1','4','2011','0''40','VR' UNION ALL

    SELECT '023','1','5','2011','0''23','VR' UNION ALL

    SELECT '023','1','6','2011','0''30','VR' UNION ALL

    SELECT '023','1','7','2011','0''19','VR' UNION ALL

    SELECT '023','1','8','2011','0''0','VR' UNION ALL

  • Yeah, I was afraid of that. You'll have to do something like this short term:

    ;with cte AS

    ( SELECT *, CONVERT( DATETIMe, CONVERT( VARCHAR(20), salesmonth) + '/' + CONVERT( VARCHAR(20), salesday) + '/' + CONVERT( VARCHAR(20), salesYear)) AS salesFullDatetime

    FROM

    Test

    )

    SELECT *

    FROM cte

    WHERE salesFullDateTime BETWEEN @startDate and @endDate

    In the long run, you'll want to convert this table to store the dates properly and get an index on it so you can let the optimizer do the majority of the work for you.


    - Craig Farrell

    Never stop learning, even if it hurts. Ego bruises are practically mandatory as you learn unless you've never risked enough to make a mistake.

    For better assistance in answering your questions[/url] | Forum Netiquette
    For index/tuning help, follow these directions.[/url] |Tally Tables[/url]

    Twitter: @AnyWayDBA

  • Craig Farrell (2/10/2011)


    Yeah, I was afraid of that. You'll have to do something like this short term:

    ;with cte AS

    ( SELECT *, CONVERT( DATETIMe, CONVERT( VARCHAR(20), salesmonth) + '/' + CONVERT( VARCHAR(20), salesday) + '/' + CONVERT( VARCHAR(20), salesYear)) AS salesFullDatetime

    FROM

    Test

    )

    SELECT *

    FROM cte

    WHERE salesFullDateTime BETWEEN @startDate and @endDate

    In the long run, you'll want to convert this table to store the dates properly and get an index on it so you can let the optimizer do the majority of the work for you.

    @Craig: Two things I would change: First, the data type (VARCHAR(20) is not really appropriate in this case) and second the order of month, day and year (add a SET DATEFORMAT dmy or SET LANGUAGE 'GERMAN' before your query and see what happens... ;-))

    The revised query would look like

    ;WITH cte AS

    (

    SELECT *,

    CAST(CONVERT( CHAR(4), salesYear)+ RIGHT(100 + salesmonth,2)+ RIGHT(100 + salesday,2) AS DATETIME) as salesFullDatetime

    FROM Test

    )

    SELECT *

    FROM cte

    WHERE salesFullDateTime BETWEEN @startDate AND @endDate

    I second your recommendation to store the data in a date column. It could even be a computed persisted column added to the current design.



    Lutz
    A pessimist is an optimist with experience.

    How to get fast answers to your question[/url]
    How to post performance related questions[/url]
    Links for Tally Table [/url] , Cross Tabs [/url] and Dynamic Cross Tabs [/url], Delimited Split Function[/url]

  • LutzM (2/10/2011)


    @Craig: Two things I would change: First, the data type (VARCHAR(20) is not really appropriate in this case) and second the order of month, day and year (add a SET DATEFORMAT dmy or SET LANGUAGE 'GERMAN' before your query and see what happens... ;-))

    Yeah, I thought of that after, but I figured he'd come back with exploding query complaints if it ended up as a problem. 🙂 You're right, though, I should have addressed it in the first pass.

    I used VARCHAR(20) because I was being lazy and couldn't remember if the string would end up concatonated if I used VC(4) for the year and (2) for the month/day during the concatonation conversion.

    The revised query would look like

    ;WITH cte AS

    (

    SELECT *,

    CAST(CONVERT( CHAR(4), salesYear)+ RIGHT(100 + salesmonth,2)+ RIGHT(100 + salesday,2) AS DATETIME) as salesFullDatetime

    FROM Test

    )

    SELECT *

    FROM cte

    WHERE salesFullDateTime BETWEEN @startDate AND @endDate

    Hm, YYYYMMDD format? Right right... ISO conversion. Good call. I like the bit with the 100+ instead of replication routines. Nice touch. Kinda surprised at the implicit conversion in the RIGHT() statement, though.


    - Craig Farrell

    Never stop learning, even if it hurts. Ego bruises are practically mandatory as you learn unless you've never risked enough to make a mistake.

    For better assistance in answering your questions[/url] | Forum Netiquette
    For index/tuning help, follow these directions.[/url] |Tally Tables[/url]

    Twitter: @AnyWayDBA

  • Craig Farrell (2/10/2011)


    ...

    Hm, YYYYMMDD format? Right right... ISO conversion. Good call. I like the bit with the 100+ instead of replication routines. Nice touch. Kinda surprised at the implicit conversion in the RIGHT() statement, though.

    Regarding the implicit conversion (straight from BOL):

    character_expression can be of any data type, except text or ntext, that can be implicitly converted to varchar or nvarchar. Otherwise, use the CAST function to explicitly convert character_expression.

    But who'd look up RIGHT() in BOL? :hehe:



    Lutz
    A pessimist is an optimist with experience.

    How to get fast answers to your question[/url]
    How to post performance related questions[/url]
    Links for Tally Table [/url] , Cross Tabs [/url] and Dynamic Cross Tabs [/url], Delimited Split Function[/url]

  • Thanks It worked!

  • schauhan13 (2/10/2011)


    I have a table in which date is divided into 3 columns salesyear,salesmonth and salesday.

    Now I need to create a sql select query for a date range say from 1/20/2010 to 2/9/2010.

    I am not sure how to do that.Please help!

    My recommendation would be to convert the table to have a real DATETIME datatype in it instead of the individual columns. Since you probably can't do that, my second recommendation would be to add a persisted computed column with the following formlua in it and then query that column...

    DATEADD(yy,SalesYear-1900,DATEADD(dd,SalesDay-1,DATEADD(mm,SalesMonth-1,0)))

    If no mods to the table are allowed, you could build a "sister table" with the correct data. Last and least, you could also build a view with the forumul I posted above.

    The formula above is VERY fast because it doesn't have any character based conversions and only uses integer math.

    --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 9 posts - 1 through 8 (of 8 total)

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