CONDITIONAL SELECT - HELP

  • Yes now I am getting exact result

    Thank you..

    🙂

  • You're welcome.

    Of course we have no idea about volume of data, so that may not be the best approach....but hopefully it gives you enough information to at least have a go yourself?

    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]

  • Good stuff here - I like the other options!

    -- Cory

  • If you don't need the identity column, or any other non-grouped data, I think you can do it all in one step, like so:

    SELECT

    Code

    ,COALESCE(MAX(CASE WHEN Type = 'CORRECTED' THEN Amount ELSE NULL END),

    MAX(CASE WHEN Type = 'ACTUAL' THEN Amount ELSE NULL END),

    MAX(CASE WHEN Type = 'ESTIMATED' THEN Amount ELSE NULL END)) AS Amount

    ,COALESCE(MAX(CASE WHEN Type = 'CORRECTED' THEN 'CORRECTED' ELSE NULL END),

    MAX(CASE WHEN Type = 'ACTUAL' THEN 'ACTUAL' ELSE NULL END),

    MAX(CASE WHEN Type = 'ESTIMATED' THEN 'ESTIMATED' ELSE NULL END)) AS Type

    ,[Month]

    ,[Year]

    FROM #Test

    GROUP BY Code,[Year],[Month]

    ORDER BY Code,[Year],[Month]

    Scott Pletcher, SQL Server MVP 2008-2010

  • It is simple and good logic

    🙂

  • [n/a, removed]

    Scott Pletcher, SQL Server MVP 2008-2010

  • mister.magoo (6/22/2010)


    Another surprise (to me at least ) is that it only does one table scan of #test..

    Only on 2005 and above, but it is an example of how sophisticated the query optimiser is.

    In this case, it recognises that your SQL2K-compatible syntax is logically equivalent to a MIN(CASE...END) OVER (...) construction. Doing that transformation (exploration) results in a much better plan, with just the single scan and a common sub-expression spool.

    Not too many SQL DBAs would be able to make that transformation by visual inspection. The optimiser is a truly amazing piece of kit.

    Paul

  • Paul White NZ (6/25/2010)


    ...Not too many SQL DBAs would be able to make that transformation by visual inspection. The optimiser is a truly amazing piece of kit.

    ...

    Can't disagree.

    It just a bit unpredictable sometimes...:-D

    My favoured one is "devision by zero error" in

    SELECT Col1/Col2 FROM MyTable WHERE Col2 != 0

    (I know I 've already mentioned it few times here...):hehe:

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • We can help the optimiser even more by adding a computed column. This won't add any data to the table - it's just a metadata change - but the effect on the query plan is dramatic, producing one of my all-time favourites: the Segment Top...

    -- Not persisted!

    ALTER TABLE #Test

    ADD sort_value

    AS CASE [Type]

    WHEN 'ESTIMATED' THEN 200

    WHEN 'ACTUAL' THEN 400

    WHEN 'CORRECTED' THEN 600

    END;

    My submission is then:

    SELECT T.Code,

    T.Amount,

    T.Type,

    T.[Month],

    T.[year]

    FROM #Test T

    WHERE T.sort_value =

    (

    SELECT MAX(T2.sort_value)

    FROM #Test T2

    WHERE T2.Code = T.Code

    AND T2.[year] = T.[year]

    AND T2.[Month] = T.[Month]

    );

    Query plan (with Segment Top):

    We don't even have to explicitly reference the computed column to get this nice plan:

    SELECT T.Code,

    T.Amount,

    T.Type,

    T.[Month],

    T.[year]

    FROM #Test T

    WHERE CASE T.[Type] WHEN 'ESTIMATED' THEN 200 WHEN 'ACTUAL' THEN 400 WHEN 'CORRECTED' THEN 600 END =

    (

    SELECT MAX(CASE T2.[Type] WHEN 'ESTIMATED' THEN 200 WHEN 'ACTUAL' THEN 400 WHEN 'CORRECTED' THEN 600 END)

    FROM #Test T2

    WHERE T2.Code = T.Code

    AND T2.[year] = T.[year]

    AND T2.[Month] = T.[Month]

    );

    Clever stuff. Another benefit is that SQL Server (or you) can create statistics on the computed column to give the optimiser information about the distribution and frequency of values resulting from that CASE expression - a very powerful technique.

    Paul

  • Eugene Elutin (6/25/2010)


    It just a bit unpredictable sometimes...

    My favoured one is "division by zero error" in SELECT Col1/Col2 FROM MyTable WHERE Col2 != 0

    That's not unpredictable...it's a (good) design trade-off.

    It's the price you pay for the amazing tricks the QO can do for you: You cannot safely write code that depends on order of evaluation of scalar expressions (or even the number of times the expression might be evaluated) - though there are some supported exceptions to that, CASE expression evaluation order for example.

    My personal view is that this is a price well worth paying. I don't regard "SELECT Col1/Col2 FROM MyTable WHERE Col2 != 0" as a particularly shining example of good coding anyway 😛

    Paul

  • Paul White NZ (6/25/2010)


    Eugene Elutin (6/25/2010)


    It just a bit unpredictable sometimes...

    My favoured one is "division by zero error" in SELECT Col1/Col2 FROM MyTable WHERE Col2 != 0

    That's not unpredictable...it's a (good) design trade-off.

    ...

    You cannot safely write code that depends on order of evaluation of scalar expressions

    ...

    I don't regard "SELECT Col1/Col2 FROM MyTable WHERE Col2 != 0" as a particularly shining example of good coding anyway 😛

    ...

    I guess the only problem with such "trade-offs" that they come as new hidden features, but they are not expected by most of the existing users. Who will really love it, especially after they would successfully test upgrading from SQL2000 to SQL2005, and start to have some strange behaviour in production (which not always reproducable). I don't think it was mentioned by MS in their SQL2005 release "New Grate SQLServer Features" or "Warning! Be Aware" papers.

    I agree, that no one should write code that depends on order of evaluation of scalar expressions. The problem is: there are a lot of code already written. You know, that it is now and then, someone here having problem which is direct result of it.

    Actually, I am wrong here, it is not a problem - it is a bonanza for contractors :-D. I always say that if it not MS, we would have much less jobs around...

    "SELECT Col1/Col2 FROM MyTable WHERE Col2 != 0" is a bit grotesque. But I think it's quite representative for this feature.

    SQL Developers needs to be aware that this can happen with any kind of expression including "safe" datatype convertions (it was one thread about it today).

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Viewing 11 posts - 16 through 25 (of 25 total)

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