Multi Column Sort

  • It will work with a more sparse data set than the one provided by Barry too. Here's how it works:

    Determine the minimum values for each column

    Identify the row which contains only minimum values or nulls - this is the "first" row

    Insert the ID of this row into a results table with an identity column

    Rinse and repeat:

    Determine the minimum values for each column excluding the rows which have already been captured into the results table.

    Which is roughly the same as this:

    DROP TABLE #Result

    CREATE TABLE #Result

    (RowID INT IDENTITY(1, 1),

    ID INT PRIMARY KEY CLUSTERED)

    --

    WHILE (SELECT COUNT(*) FROM #Result) < 100

    BEGIN

    INSERT INTO #Result ([ID])

    SELECT s.[ID]

    FROM SortedColumnsTestData s

    INNER JOIN (SELECT MIN(col1) AS col1, MIN(col2) AS col2, MIN(col3) AS col3, MIN(col4) AS col4, MIN(col5) AS col5, MIN(col6) AS col6, MIN(col7) AS col7, MIN(col8) AS col8

    FROM SortedColumnsTestData m WHERE NOT EXISTS (SELECT 1 FROM #Result WHERE [ID] = m.[ID])) m ON

    m.col1 = ISNULL(s.col1, m.col1)

    AND m.col2 = ISNULL(s.col2, m.col2)

    AND m.col3 = ISNULL(s.col3, m.col3)

    AND m.col4 = ISNULL(s.col4, m.col4)

    AND m.col5 = ISNULL(s.col5, m.col5)

    AND m.col6 = ISNULL(s.col6, m.col6)

    AND m.col7 = ISNULL(s.col7, m.col7)

    AND m.col8 = ISNULL(s.col8, m.col8)

    WHERE s.CorrectSequence <= 100

    END

    --

    SELECT s.*

    FROM SortedColumnsTestData s

    INNER JOIN #Result r ON r.[ID] = s.[ID]

    ORDER BY r.RowID

    A little more challenging is converting this RBAR code into something set-based.

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • Greate job Chris!

    But you too will have to check for mutually exclusive records as with Mr Magoos test data.

    EDIT: I tried your algorithm with the sample data provided by Mr Magoo, and I can't get past record 98.


    N 56°04'39.16"
    E 12°55'05.25"

  • Peso, you seem to have got that spot on now - I have run through a few different sets of data from low to high population and it is quick and accurate. Great work!

    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]

  • Peso (4/13/2009)


    Greate job Chris!

    But you too will have to check for mutually exclusive records as with Mr Magoos test data.

    EDIT: I tried your algorithm with the sample data provided by Mr Magoo, and I can't get past record 98.

    Good catch, mate. It fails at row 98 because the minimum values for col7 and col8 are null. That's easy enough to fix (AND (m.col8 = ISNULL(s.col8, m.col8) or m.col8 is null)).

    It also fails on the same two rows as your solution(-1) because both rows contain only minimum column values and nulls, and from the same set. That's less easy to fix 😛

    Nice work, Peter, that's a great solution - as always 😎

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • Thank you both.

    Let's hear what Barry has to say about it.

    Attached are second revision to deal with sample data provided by Barry.

    It also works with the sample data provided by Magoo.


    N 56°04'39.16"
    E 12°55'05.25"

  • Heh. I am a little behind on this, Peso. And I have another meeting tonight, so I am not sure if I can get before tomorrow night. 🙁

    [font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
    Proactive Performance Solutions, Inc.
    [/font]
    [font="Verdana"] "Performance is our middle name."[/font]

  • It's OK! Don't worry.

    I have nothing to do besides awaiting the results from Adam's competition.

    And for jsanborn to test the 2nd revision of the algorithm.


    N 56°04'39.16"
    E 12°55'05.25"

  • Sorry, too many meetings this week. I did test an algorithm posted a couple days ago. I opened it and executed it without touching any of it but it was returning 0 rows on several tries and twenty something rows on other tries. I'll look for the second version and give it a try.

  • If there is a discrepancy between your test data and the test data supplied by both Mr Magoo and Mr Young, I would like to know.

    The 2nd revision of the algorithm works with both sample data provided by the both above mentioned gentlemen.


    N 56°04'39.16"
    E 12°55'05.25"

  • Peso (4/14/2009)


    It's OK! Don't worry.

    I have nothing to do besides awaiting the results from Adam's competition.

    Heh, yeah. The day after the entry period closed for Adam's contest, I found two typo's of leftover diagnostic code in my submissions that make that run twice as slow. 🙁 I definitely need some time off.

    [font="Times New Roman"]-- RBarryYoung[/font], [font="Times New Roman"] (302)375-0451[/font] blog: MovingSQL.com, Twitter: @RBarryYoung[font="Arial Black"]
    Proactive Performance Solutions, Inc.
    [/font]
    [font="Verdana"] "Performance is our middle name."[/font]

  • If there is a discrepancy between your test data and the test data supplied by both Mr Magoo and Mr Young, I would like to know.

    The 2nd revision of the algorithm works with both sample data provided by the both above mentioned gentlemen.

    If that was for me, I haven't tried 2nd revision yet. Will try and get to it soon.

  • Here is another approach to this problem that I have not seen yet on this thread.

    done based on mister magoo's testdata...

    /*

    * get all values into single column

    */

    SELECT id, colvalue = col1 INTO #testtemp FROM #testdata WHERE col1 IS NOT NULL

    UNION ALL

    SELECT id, col2 FROM #testdata WHERE col2 IS NOT NULL

    UNION ALL

    SELECT id, col3 FROM #testdata WHERE col3 IS NOT NULL

    UNION ALL

    SELECT id, col4 FROM #testdata WHERE col4 IS NOT NULL

    UNION ALL

    SELECT id, col5 FROM #testdata WHERE col5 IS NOT NULL

    UNION ALL

    SELECT id, col6 FROM #testdata WHERE col6 IS NOT NULL

    UNION ALL

    SELECT id, col7 FROM #testdata WHERE col7 IS NOT NULL

    UNION ALL

    SELECT id, col8 FROM #testdata WHERE col8 IS NOT NULL;

    GO

    /*

    * order values

    */

    SELECT id, colvalue, valueorder = IDENTITY(INT, 1, 1)

    INTO #testorder

    FROM #testtemp

    ORDER BY colvalue;

    GO

    DROP TABLE #testtemp;

    GO

    /*

    * get rows in value order

    */

    SELECT sup.id, sup.col1, sup.col2, sup.col3, sup.col4, sup.col5, sup.col7, sup.col8

    FROM #testdata sup

    INNER JOIN

    (SELECT id, roworder = MIN(valueorder)

    FROM #testorder

    GROUP BY id) sub

    ON sub.id=sup.id

    ORDER BY sub.roworder;

    GO

    DROP TABLE #testorder;

    GO

  • Hi, If the correctly ordered sample you gave is typical of the data the correct sort order is simply the average of all values > 0 😎

    eg:,

    Row1: 4.4225

    Row2: 4.9325

    Row3: 5.104286

    Row4: 5.503333

  • Not really.

    Try with the sample data provided by Mr Young.

    AVGCorrectSequence

    0.848343807091231

    1.941816529992232

    3.1029747509888821

    3.637067671983737

    3.7789496156818643

    4.224919996747955


    N 56°04'39.16"
    E 12°55'05.25"

  • The random occurrence of nulls makes that not work. It's not common, but it's possible to have half the columns in a row be null.

  • Viewing 15 posts - 166 through 180 (of 180 total)

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