gondor: Tabelle auslesen via UNION

Hallo,

ich lese Einträge aus einer Tabelle wie folgt aus:

Erst kommen die Einträge mit...
1. alle top!=0 AND color=0 und status=expert
2. alle top=0 AND color!=0 und status=expert
3. alle top=0 AND color=0 und status=expert
4. alle status=basic

Tabelle:

id | top | color | type (basic, expert) | created on
1  | 1   | 0     | expert  | 2009-01-05 15:54:26
2  | 2   | 0     | expert  | 2009-01-06 15:54:26
3  | 3   | 0     | expert  | 2009-01-04 15:54:26
4  | 2   | 0     | expert  | 2009-01-06 15:54:26
5  | 0   | 0     | basic    | 2009-01-07 15:54:26
5  | 0   | 1     | expert  | 2009-01-16 15:54:26
6  | 0   | 0     | basic  | 2009-01-09 15:54:26
7  | 0   | 2     | expert  | 2009-01-12 15:54:26
8  | 0   | 0     | expert  | 2009-01-06 15:54:26
9  | 0   | 1     | expert  | 2009-01-08 15:54:26
10 | 0   | 3     | expert  | 2009-01-04 15:54:26
11 | 0   | 2     | expert  | 2009-01-03 15:54:26
12 | 0   | 0     | basic  | 2009-01-08 15:54:26
13 | 0   | 1     | expert  | 2009-01-06 15:54:26

Meine Query dazu:

(
SELECT *
FROM table
WHERE top!=0 AND color=0 AND type='expert' ORDER BY created_on DESC
UNION
(
SELECT *
FROM table
WHERE top=0 AND color!=0 AND type='expert' ORDER BY created_on ASC
)
UNION
(
SELECT *
FROM table
WHERE top=0 AND color=0 AND type='expert' ORDER BY created_on ASC
)
UNION
(
SELECT *
FROM table
WHERE type='basic' ORDER BY created_on ASC
)
LIMIT 0, 100

Leider funktioniert das nicht, da die Einträge nicht wie gewollt nach Datum (oder was anderem) sortiert werden...

Jemand eine Idee, wieso?

Danke,
gondor

  1. Hi,

    Leider funktioniert das nicht, da die Einträge nicht wie gewollt nach Datum (oder was anderem) sortiert werden...

    Doch, werden sie - innerhalb der einzelnen Selects natuerlich, denn da hast du angegeben, dass sortiert werden soll.

    Jemand eine Idee

    Ja - RTFM :-)

    MfG ChrisB

    --
    „This is the author's opinion, not necessarily that of Starbucks.“
    1. yo,

      Doch, werden sie - innerhalb der einzelnen Selects natuerlich, denn da hast du angegeben, dass sortiert werden soll.

      wenn ich die doku richtig verstanden habe, wird genau das nicht passieren, sieht so aus, als wenn es nur in kombination mit LIMIT geht.

      [Link:http://dev.mysql.com/doc/refman/5.1/de/union.html]

      Ilja

      1. Hi,

        Doch, werden sie - innerhalb der einzelnen Selects natuerlich, denn da hast du angegeben, dass sortiert werden soll.

        wenn ich die doku richtig verstanden habe, wird genau das nicht passieren, sieht so aus, als wenn es nur in kombination mit LIMIT geht.

        http://dev.mysql.com/doc/refman/5.1/de/union.html

        Auf welche Aussage genau beziehst du dich da?

        MfG ChrisB

        --
        „This is the author's opinion, not necessarily that of Starbucks.“
        1. Hello,

          Auf welche Aussage genau beziehst du dich da?

          vielleicht auf:
          --
          (SELECT a FROM tbl_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
          UNION
          (SELECT a FROM tbl_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

          Das Einfügen von ORDER BY bei einzelnen SELECT-Anweisungen in Klammern hat nur in Kombination mit LIMIT Auswirkungen. Andernfalls wird ORDER BY wegoptimiert.
          --

          MfG
          Rouven

          --
          -------------------
          sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
          Inter Arma Enim Silent Leges  --  Cicero
        2. yo,

          http://dev.mysql.com/doc/refman/5.1/de/union.html

          Auf welche Aussage genau beziehst du dich da?

          ich irre mich bezüglich den eigenheiten von mysql ja schon mal öfters, aber diese aussage bringt mich dazu.

          "Das Einfügen von ORDER BY bei einzelnen SELECT-Anweisungen in Klammern hat nur in Kombination mit LIMIT Auswirkungen. Andernfalls wird ORDER BY wegoptimiert."

          und ich musss gestehen, sie macht auch sind, weil sie damit nicht zur sortierung, sondern zur selektion eingesetzt wird.

          Ilja

    2. Hallo ChrisB,

      bin leider noch nicht schlauer geworden. Wenn ich ein LIMIT innerhalb des UNION-Selects setze, verhindere ich aber, dass mir die Einträge nicht so ausgegeben werden wie gewünscht, oder?

      Ich möchte ja zuerst ALLE Einträge geordnet nach Wunsch mit

      top!=0 and color=0 and type=expert

      dann ALLE Einträge geordnet nach Wunsch mit

      top=0 and color!=0 and type=expert

      dann ALLE Einträge geordnet nach Wunsch mit

      top=0 and color=0 and type=expert

      und ALLE Einträge geordnet nach Wunsch mit

      type=basic

      Mit einem LIMIT verhindere ich das doch, oder?

      Außerdem möchte ich die gesamte Liste (also, den Result) über ein Limit beschränken... steh also noch ein wenig auf'n Schlauch.

      Vllt. gibt es ja noch einen eleganteren Weg?

      gondor(..)

      Jemand eine Idee

      Ja - RTFM :-)

      MfG ChrisB

      1. Hello,

        Vllt. gibt es ja noch einen eleganteren Weg?

        mehrere. Ich finde leider mein Posting zu deiner Ausgangsfrage nicht mehr, ich hatte dir dort neben UNION noch eine Lösung mit CASE vorgestellt, die deinen Bedürfnissen jetzt wahrscheinlich eher entsprechen würde.

        bin leider noch nicht schlauer geworden. Wenn ich ein LIMIT innerhalb des UNION-Selects setze, verhindere ich aber, dass mir die Einträge nicht so ausgegeben werden wie gewünscht, oder?

        jetzt musst du mir nochmal verraten was du möchtest - ich verstehe dich so, dass es diese "4 Kategorien" von Treffern gibt, die du mit einer gewissen Priorität selektieren möchtest. Über alle Treffer möchtest du eine Sortierung laufen lassen? Oder innerhalb der Gruppen? Am Ende sollen es maximal 100 Treffer werden?!
        Was hindert dich daran, das LIMIT mit in die SELECTs zu setzen, du weißt, dass am Ende maximal 100 Treffer übrig bleiben, im Worst Case liefert also ein einzelnes Subselect alle 100 Treffer. Na gut, dann lass halt jedes Subselect selbst auch mit LIMIT 100 arbeiten. Das Ergebnis der 4 Unions sind dann maximal 400 Treffer, nach deinen Wünschen sortiert, von denen du dann per LIMIT 100 die ersten 100 herausgreifst.
        (SELECT .. FROM .. ORDER BY ..LIMIT 100)
        UNION
        ...
        LIMIT 100

        MfG
        Rouven

        --
        -------------------
        sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
        Computer programming is tremendous fun. Like music, it is a skill that derives from an unknown blend of innate talent and constant practice. Like drawing, it can be shaped to a variety of ends: commercial, artistic, and pure entertainment. Programmers have a well-deserved reputation for working long hours but are rarely credited with being driven by creative fevers. Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination, but because their imagination reveals worlds that others cannot see. -- Larry OBrien and Bruce Eckel in Thinking in C#
        1. jetzt musst du mir nochmal verraten was du möchtest - ich verstehe dich so, dass es diese "4 Kategorien" von Treffern gibt, die du mit einer gewissen Priorität selektieren möchtest. Über alle Treffer möchtest du eine Sortierung laufen lassen? Oder innerhalb der Gruppen? Am Ende sollen es maximal 100 Treffer werden?!
          Was hindert dich daran, das LIMIT mit in die SELECTs zu setzen, du weißt, dass am Ende maximal 100 Treffer übrig bleiben, im Worst Case liefert also ein einzelnes Subselect alle 100 Treffer. Na gut, dann lass halt jedes Subselect selbst auch mit LIMIT 100 arbeiten. Das Ergebnis der 4 Unions sind dann maximal 400 Treffer, nach deinen Wünschen sortiert, von denen du dann per LIMIT 100 die ersten 100 herausgreifst.
          (SELECT .. FROM .. ORDER BY ..LIMIT 100)
          UNION
          ...
          LIMIT 100

          Hallo Rouven,

          das kann ich machen, habe jedoch im Falle einer Seitennavigation ein gefälschtes Ergebnis. Das Limit müsste aus den einzelnen Selects raus und nur am Ende stehen.

          dass es diese "4 Kategorien" von Treffern gibt, die du mit einer gewissen Priorität selektieren möchtest.

          • ja

          Über alle Treffer möchtest du eine Sortierung laufen lassen?

          • nein

          Oder innerhalb der Gruppen?

          • ja

          Am Ende sollen es maximal 100 Treffer werden?!

          • nicht unbedingt. Ich möchtte eigentlich alle Treffer und diese Menge durch ein Limit beschränken.

          Du hattest mit diesen Ansatz gegeben:

          (2) künstliches Einbringen einer Sortierspalte
          SELECT id,
                 top,
                 color,
                 type,
                 CASE
                   WHEN (top != 0 AND color = 0 AND status='expert') THEN 1
                   WHEN (top=0 AND color!=0 AND status = 'expert') THEN 2
                   ...
                 END AS sortierung
          FROM tabelle
          ORDER BY sortierung

          Gruß,
          gondor(..)

          1. Hello,

            Oder innerhalb der Gruppen?

            • ja

            was hindert dich dann darin, ORDER BY und LIMIT innerhalb des Subselect anzubringen - das Order By greift.

            • nicht unbedingt. Ich möchtte eigentlich alle Treffer und diese Menge durch ein Limit beschränken.

            genau, und wenn du weißt, dass du auf maximal X Treffer beschränken wirst, dann ist es ja auch kein Problem, wenn jedes Subselect schon maximal X Treffer liefert (anstatt alle) - oder klär mich auf, wo ich dich falsch verstehe.

            Du hattest mit diesen Ansatz gegeben:

            d.h. wenn du hier erst nach Sortierspalte und dann nach Datum sortierst und eine LIMIT 100 platzierst, dann müsste es auf das selbe rauskommen wie meine obige Ausführung.

            MfG
            Rouven

            --
            -------------------
            sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
            We found ourselves looking upon a familiar sight. We were home. How do you pick up the threads of an old life? How do you go on... when in your heart you begin to understand... there is no going back? There are somethings that time cannot mend... some hurts that go too deep... that have taken hold.  --  The Lord of the Rings: The Return of the King (Peter Jackson)
            1. Hello,

              Moin moin ;-)

              Oder innerhalb der Gruppen?

              • ja
                was hindert dich dann darin, ORDER BY und LIMIT innerhalb des Subselect anzubringen - das Order By greift.
              • nicht unbedingt. Ich möchtte eigentlich alle Treffer und diese Menge durch ein Limit beschränken.
                genau, und wenn du weißt, dass du auf maximal X Treffer beschränken wirst, dann ist es ja auch kein Problem, wenn jedes Subselect schon maximal X Treffer liefert (anstatt alle) - oder klär mich auf, wo ich dich falsch verstehe.

              Okay, wenn ich die Einträge ohne ein Limit auslese ist das kein Problem. Möchte ich jedoch die Einträge über eine Seitennavigation steuern, würde das Ergebnis doch verfälscht ausgegeben werden oder:

              z.b.

              Seite 1 Limit 0, 10

              alle Top und expert (3 Einträge)
              alle Color und expert (6 Einträge)
              alle !Top und !Color und expert (1 Eintrag)

              Seite 2 Limit 10, 10
              restlichen !Top und !Color und expert (4 Eintrag)
              alle basic (6 Einträge)

              Seite 3 Limit 20, 10
              alle basic (10 Einträge)

              usw...

              Erzwingt das Limit in den Select-Anweisungen nicht, das auf der 3. Seite z.b. wieder Top-Einträge gelistet werden? Wenn z.b. für Seite 3 in jeder Anweisung Limit 20, 10 steht kommen doch erst wieder alle Top, dann Color, usw... anstatt nur die basic zu liefern, da auf den vorderen Seiten die Einträge doch schon 'abgefrühstückt' wurden.

              Oder habe ich hier ein Verständnisproblem?

              Du hattest mit diesen Ansatz gegeben:
              d.h. wenn du hier erst nach Sortierspalte und dann nach Datum sortierst und eine LIMIT 100 platzierst, dann müsste es auf das selbe rauskommen wie meine obige Ausführung.

              Hmm... laut Test funktioniert diese Anweisung nicht wie gewünscht.

              MfG
              Rouven

              Problem verstanden?

              gondor(..)

              1. Hello,

                Seite 1 Limit 0, 10
                Seite 2 Limit 10, 10

                mein Hirn leidet noch unter einer zu langen Superbowlnacht, aber das klingt in der Tat erstmal nach einem Problem, weil du auf der Folgeseite wissen müsstest, welche Sätze auf Seite 1 zu sehen waren.

                Hmm... laut Test funktioniert diese Anweisung nicht wie gewünscht.

                wie sieht sie jetzt aus und was heißt das?

                MfG
                Rouven

                --
                -------------------
                sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
                I will never understand why Germans feel the need to kill trees  --  Arbeitskollege aus UK zum Thema ob eine Dokumentation elektronisch oder auf Papier ausgeliefert wird
                1. yo,

                  mein Hirn leidet noch unter einer zu langen Superbowlnacht

                  habe ich auch live gesehen, war am ende sehr gut und spannend, habe ja den Cardinals die daumen gedrückt....

                  Ilja

                  1. Hello,

                    habe ich auch live gesehen, war am ende sehr gut und spannend, habe ja den Cardinals die daumen gedrückt....

                    jo, fand ich auch - am Anfang des vierten Quarters habe ich ernsthaft mal gedacht es wäre rum, zu großer Abstand, aber dann ging es doch alles irgendwie ziemlich schnell, hätte ich nicht gedacht...hat sich auf jeden Fall gelohnt.

                    MfG
                    Rouven

                    --
                    -------------------
                    sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
                    Wenn du die Nadel im Heuhaufen nicht findest, zünde den Heuhaufen an.
                    1. jo, fand ich auch - am Anfang des vierten Quarters habe ich ernsthaft mal gedacht es wäre rum, zu großer Abstand, aber dann ging es doch alles irgendwie ziemlich schnell, hätte ich nicht gedacht...hat sich auf jeden Fall gelohnt.

                      jep, am ende war noch mal richtig dynamik drinn. ich hätte es ja dem alten mann gegönnt. schade das es die interception am ende der ersten hälte gab, sonst hätten sie es gepackt.

                      Ilja

                      1. Hello,

                        jep, am ende war noch mal richtig dynamik drinn. ich hätte es ja dem alten mann gegönnt. schade das es die interception am ende der ersten hälte gab, sonst hätten sie es gepackt.

                        die interception war sowieso eine aus der kategorie "gibts nicht", sich da so die butter vom brot nehmen zu lassen...wobei roethlisberger schon vorher ein paar mal mehr fällig gewesen wäre, ich erinnere mich da an einen pass, den er geworfen hat, nachdem er eigentlich schon gestolpert und halb getacklelt wurde. sowas machts dann halt schwer.
                        und ganz ehrlich, solange es sich die cardinals leisten beim Fieldgoal den Ballhalter umzulaufen - na ja, immerhin haben sie die nächsten drei downs abgewehrt...

                        MfG
                        Rouven

                        --
                        -------------------
                        sh:| fo:} ch:? rl:( br:& n4:{ ie:| mo:} va:) js:| de:] zu:| fl:( ss:) ls:& (SelfCode)
                        Friendships are a lot like a backyard garden. We plan to tend to them, but we just always seem to put it off until next week. --  Christian Clemenson as Jerry Espenson in Boston Legal: "Patriot Acts"
  2. Hi,

    Erst kommen die Einträge mit...

    1. alle top!=0 AND color=0 und status=expert
    2. alle top=0 AND color!=0 und status=expert
    3. alle top=0 AND color=0 und status=expert
    4. alle status=basic

    Ich würde das ohne UNION lösen.
    Du willst alle mit "(color=0 or top=0) and status=expert) or status=basic".

    Leider funktioniert das nicht, da die Einträge nicht wie gewollt nach Datum (oder was anderem) sortiert werden...

    Jemand eine Idee, wieso?

    Die Sortierung müsstest du soweit ich weiß erst nach der Verknüfung, also da wo LIMIT steht, machen.
    Aber das UNION wird hier ja eh nicht gebraucht.

    mfG,
    steckl