Rewriting the query without using 'Insert' <Query Optimization>

  • Hello,

    I have a table with columns ID, R_DATE, CATEGORY. What I have to do is to pull out all the records with most recent R_DATE and CATEGORY as one of 'CC' or 'MB'

    ID R_DATE CATEGORY

    --------------------------------

    D142 12/12/08 CC

    S213 10/11/08 CA

    S563 07/08/10 MB

    S421 05/21/09 MB

    F367 01/30/07 CA

    D142 08/24/07 MB

    What I have done is

    STEP:1 (Pulls out all records with CATEGORY value as 'CC' or 'MB')

    INSERT INTO STABLE_TMP

    ( ID,R_DATE,CATEGORY)

    SELECT DISTINCT

    a.ID,a.R_DATE,a.CATEGORY,

    from

    ( SELECT

    ID,R_DATE,CATEGORY

    FROM STABLE where CATEGORY = 'CC'

    OR CATEGORY = 'MB' )a

    STEP:2 (Pulls out the records with most recent R_DATE from the resulting table of STEP: 1)

    SELECT

    a.ID,a.R_DATE,a.CATEGORY,

    from

    (select ID,R_DATE,CATEGORY ROW_NUMBER() over (partition by ID

    order by R_DATE desc) as Rno

    from STABLE_TMP

    )a

    WHERE a.Rno=1

    Everything works fine. But, Can I accomplish the task without having the STABLE_TMP in between. Can I optimize it further??

  • You could either use a subquery with MAX() and GROUP BY or change the PARTITION BY part in your ROW_NUMBER subquery and use it directly against your source table.

    As a side note: this is homework, right?



    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]

  • I got the solution.

    @LutzM: Thanks for ur hlp. Its not the homework BTW, the problem is far more complex.

    I jz drilled it down to look like simple one.

    The following will work

    select a.ID,a.R_DATE,a.CATEGORY from

    (select b.ID,

    b.R_DATE,

    b.CATEGORY,

    ROW_NUMBER() over (partition by b.ID

    order by b.R_DATE desc) as Rno

    from

    ( SELECT

    ID, R_DATE, CATEGORY FROM STABLE

    where SHRNCRS_NCST_CODE = 'CC'

    OR SHRNCRS_NCST_CODE = 'MB'

    )b

    )a

    where a.Rno = 1

  • Wouldn't the following return the same result?

    ;WITH cte AS

    (

    SELECT

    ID,

    R_DATE,

    CATEGORY,

    ROW_NUMBER() OVER (PARTITION BY SHRNCRS_NCST_CODEORDER BY R_DATE DESC) Rno

    FROM STABLE

    WHERE SHRNCRS_NCST_CODE IN('CC', 'MB')

    )

    SELECT *

    FROM cte

    WHERE Rno=1



    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]

  • Well, Even though I am not good at using CT Expressions, According to my knowledge, the following should work. But, if I try this, Its showing error "FROM keyword not found where expected"

    WITH cte AS

    (

    SELECT

    *, ROW_NUMBER() over (partition by ID

    order by R_DATE desc) as Rno

    FROM STABLE

    WHERE SHRNCRS_NCST_CODE IN('CC', 'MB')

    )

    SELECT *

    FROM cte

    WHERE Rno=1

  • Strange. Should work. Is this the full query you posted?



    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]

  • If this isn't the first statement in the batch, you need a semicolon.

    Change:

    WITH cte AS

    to:

    ;WITH cte AS


    - 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

  • Tried that too, Still no change !!

  • Here's a test scenario showing that your code should work.

    Beside the table name, what's different on your end?

    DECLARE @tbl TABLE

    (

    ID INT,R_DATE DATETIME, SHRNCRS_NCST_CODE CHAR(2)

    )

    INSERT INTO @tbl

    SELECT 1,'12/12/08 ','CC' UNION ALL

    SELECT 1,'12/14/08 ','CC'

    ;WITH cte AS

    (

    SELECT

    *, ROW_NUMBER() OVER (PARTITION BY ID

    ORDER BY R_DATE DESC) AS Rno

    FROM @tbl

    WHERE SHRNCRS_NCST_CODE IN('CC', 'MB')

    )

    SELECT *

    FROM cte

    WHERE Rno=1



    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]

  • mounish (1/10/2011)


    Tried that too, Still no change !!

    Heh, and if you can't easily compare what you have to Lutz, it sounds like you've buried this in a larger query... can you pop the entire query up? My guess is it's complaining about a different line that might have gotten bumped while you were working on this.


    - 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

  • mounish (1/10/2011)


    Well, Even though I am not good at using CT Expressions, According to my knowledge, the following should work. But, if I try this, Its showing error "FROM keyword not found where expected"

    Isn't that an Oracle error message?

    MM



    select geometry::STGeomFromWKB(0x0106000000020000000103000000010000000B0000001000000000000840000000000000003DD8CCCCCCCCCC0840000000000000003DD8CCCCCCCCCC08408014AE47E17AFC3F040000000000104000CDCCCCCCCCEC3F9C999999999913408014AE47E17AFC3F9C99999999991340000000000000003D0000000000001440000000000000003D000000000000144000000000000000400400000000001040000000000000F03F100000000000084000000000000000401000000000000840000000000000003D0103000000010000000B000000000000000000143D000000000000003D009E99999999B93F000000000000003D009E99999999B93F8014AE47E17AFC3F400000000000F03F00CDCCCCCCCCEC3FA06666666666FE3F8014AE47E17AFC3FA06666666666FE3F000000000000003D1800000000000040000000000000003D18000000000000400000000000000040400000000000F03F000000000000F03F000000000000143D0000000000000040000000000000143D000000000000003D, 0);

  • Forum Etiquette: How to post Reporting Services problems
  • [/url]
  • Forum Etiquette: How to post data/code on a forum to get the best help - by Jeff Moden
  • [/url]
  • How to Post Performance Problems - by Gail Shaw
  • [/url]

  • mister.magoo (1/10/2011)


    mounish (1/10/2011)


    Well, Even though I am not good at using CT Expressions, According to my knowledge, the following should work. But, if I try this, Its showing error "FROM keyword not found where expected"

    Isn't that an Oracle error message?

    select *

    where blah

    from syscolumns

    Msg 156, Level 15, State 1, Line 3

    Incorrect syntax near the keyword 'from'.

    Errr, you might be right. WITH is a T-SQL convention. So is Row_Number() afaik.


    - 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 (1/10/2011)


    mister.magoo (1/10/2011)


    mounish (1/10/2011)


    Well, Even though I am not good at using CT Expressions, According to my knowledge, the following should work. But, if I try this, Its showing error "FROM keyword not found where expected"

    Isn't that an Oracle error message?

    select *

    where blah

    from syscolumns

    Msg 156, Level 15, State 1, Line 3

    Incorrect syntax near the keyword 'from'.

    Errr, you might be right. WITH is a T-SQL convention. So is Row_Number() afaik.

    Actually, WITH was available in Oracle long before SQL Server. They don't call it a "CTE", though. Instead, they call it "Sub-Query Refactoring" and it works the same way as it does in SQL Server.

    --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)

  • Jeff Moden (1/10/2011)


    Actually, WITH was available in Oracle long before SQL Server. They don't call it a "CTE", though. Instead, they call it "Sub-Query Refactoring" and it works the same way as it does in SQL Server.

    Shows ya what I know, I guess. Thanks for the correction. 🙂

    *mutters something about not talking about RDBMS's he doesn't know anymore...*


    - 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

  • Thank y'all Mates for your help.At this moment, I guess I should go with the solution I posted earlier even though, it is not simple.

    As you can see there, the solution query don't uses CTE (though it is simple).. Thanks Again!:-)

  • Viewing 15 posts - 1 through 15 (of 15 total)

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