T-Rex: Überprüfung eines Feldes in zwei unterschiedlichen Zeilen

Moin,

hab da eine Tabelle da steht sowas drin:

Row; ID; PRÜFUNG
1; 1 ; 7
2; 1 ; 8
3; 2 ; 7
4; 3 ; 10
5; 4 ; 7
6; 4 ; 8
7; 4 ; 9

Jetzt suche ich nach einem Query der mir ID 1 und 4 zurückliefert (alternativ Zeile 1,2,5,6) wenn "PRÜFUNG" sowohl 7 als auch 8 ist. Also nicht WHERE PRÜFUNG = 7 OR PRÜFUNG = 8.

Ist echt schwer rüber zu bringen was ich möchte (und ich fühle mich gerade wie ein Anfänger). Ich hoffe es ist dennoch klar?

Gruß
tranportierender
T-Rex

  1. Moin T,

    Row; ID; PRÜFUNG
    1; 1 ; 7
    2; 1 ; 8
    3; 2 ; 7
    4; 3 ; 10
    5; 4 ; 7
    6; 4 ; 8
    7; 4 ; 9

    Jetzt suche ich nach einem Query der mir ID 1 und 4 zurückliefert (alternativ Zeile 1,2,5,6) wenn "PRÜFUNG" sowohl 7 als auch 8 ist. Also nicht WHERE PRÜFUNG = 7 OR PRÜFUNG = 8.

    Naja, mit einem einfachen JOIN kriegst du das doch hin:

    SELECT tbl.* FROM tbl INNER JOIN tbl AS tbl1 ON tbl1.ID = tbl.ID AND tbl1."Prüfung" = 8 WHERE tbl."Prüfung" = 7;

    Gibt bei mir:

      
       1 |  1 |        7  
       5 |  4 |        7  
    
    

    LG,
     CK

    1. Naja, mit einem einfachen JOIN kriegst du das doch hin:

      Wuah du hast natürlich recht. Dann hab ich eine Information vergessen, mein Fehler sorry.
      Und zwar soll das ganze erweiterbar sein. 7,8,9,10,15,27. Da können theoretisch an die 20 Prüfungen kommen.

      Gruß
      halbfakten präsentierender
      T-Rex

      1. Moin T-Rex,

        was für ein DBMS benutzt du?

        LG,
         CK

        1. MySQL 5.x
          Genauer weiß ich es aus dem Kopf leider nicht, müsste ich erstmal nachgucken.

          GRuß
          Gedächtnissieb
          T-Rex

          1. Moin T-Rex,

            MySQL 5.x
            Genauer weiß ich es aus dem Kopf leider nicht, müsste ich erstmal nachgucken.

            Das habe ich befürchtet. Dafür gibt es keine schöne Lösung, denke ich. Ich habe zwei im Kopf, die eine arbeitet mit GROUP\_CONCAT() und LIKE, die anderen arbeitet mit einer correlated subquery:

            SELECT id, GROUP_CONCAT(pruefung ORDER BY pruefung ASC, ',') AS grp FROM tmp GROUP BY id HAVING grp LIKE '%7,8%';

            SELECT id AS outer_id, (SELECT COUNT(id) FROM tmp WHERE pruefung IN (7, 8) AND id = outer_id GROUP BY id) AS cnt FROM tmp GROUP BY outer_id HAVING cnt >= 2;

            Schön sind beide nicht. Aber beide liefern das gewünschte Ergebnis.

            LG,
             CK

            1. Hmm... du hast recht, schön ist das nicht. Ich denke vor allem an das debuggen, falls doch mal ein "Fehler" auftritt. Wenn die Verschachtelungen zu groß sind, wird es enorm schwer da einen Fehler zu finden.

              Um genau zu sein geht es bei der Tabelle um eine Kardinalitätstabelle. Eine n:m Auflösung. Es sind Eigenschaften die einer anderen Tabelle zugewiesen sind. Alternativ könnte ich diese Eigenschaften auch vor dem speichern in ein Datenbankfeld der Haupttabelle schieben. Sprich, das GROUP_CONCAT cachen. Würde das helfen?

              Gruß
              Like "%T-Rex%"

            2. Vergiss das andere Posting.
              Lösung zwei passt, ist erweiterbar und keine Verschachtelung wie ich dachte.

              Ist noch früh und ich hab schlecht geschlafen :(

              Gruß
              unausgeschlafener
              T-Rex

            3. Ich nochmal sorry.
              Hätte zu dem Konstrukt nochmal eine Frage.

              SELECT id AS outer_id, (SELECT COUNT(id) FROM tmp WHERE pruefung IN (7, 8) AND id = outer_id GROUP BY id) AS cnt FROM tmp GROUP BY outer_id HAVING cnt >= 2;

              Das da oben funktioniert. Ich hab es ein wenig umgestellt und dann hat es nicht funktioniert:

              SELECT id AS outer_id, (SELECT COUNT(id) FROM tmp WHERE pruefung IN (7, 8) AND id = outer_id GROUP BY id) AS cnt FROM tmp WHERE cnt >= 2;

              Dann hab ich die Fehlermeldung bekommen cnt nicht bekannt. Daraus schließe ich, dass dem MySQL Parser zu dem Zeitpunkt cnt nicht bekannt ist. Ergo wird zu erst die where Bedingung abgearbeitet. Having kommt anscheinend nach where. Richtig?

              Gruß
              umstellender
              T-Rex

              1. Moin T-Rex,

                SELECT id AS outer_id, (SELECT COUNT(id) FROM tmp WHERE pruefung IN (7, 8) AND id = outer_id GROUP BY id) AS cnt FROM tmp WHERE cnt >= 2;

                Dann hab ich die Fehlermeldung bekommen cnt nicht bekannt. Daraus schließe ich, dass dem MySQL Parser zu dem Zeitpunkt cnt nicht bekannt ist. Ergo wird zu erst die where Bedingung abgearbeitet. Having kommt anscheinend nach where. Richtig?

                Grob gesagt: WHERE wird vor der Aggregierungsphase ausgeführt, HAVING erst nach der Aggregierungsphase. HAVING filtert also das Aggregat, WHERE das Resultset.

                LG,
                 CK

              2. Tach!

                Ergo wird zu erst die where Bedingung abgearbeitet. Having kommt anscheinend nach where. Richtig?

                Pi mal Daumen ist die Reihenfolge wie folgt, wobei der Optimizer anders vorgehen kann, aber das macht er dann transparent:

                FROM mit JOINs selektiert die zu berücksichtigenden Tabellen.
                WHERE schränkt die Menge ein. Aliasnamen von Tabellen sind bekannt und können verwendet werden.
                GROUP BY fasst zusammen.
                SELECT sammelt/berechnet die Felder für die Ergebnismenge. Jetzt sind auch die dortigen Aliasnamen bekannt.
                HAVING sortiert noch ein paar Datensätze aus, üblicherweise bezogen auf Kriterien, die erst jetzt zur Verfügung stehen.
                ORDER BY sortiert den ganzen Käse, wobei Aliasnamen und auch Spaltennummern angegeben werden können.
                und LIMIT lässt den augenblicklich nicht gewollten Rest untern Tisch fallen.

                dedlfix.

                1. Jetzt noch eine Eselsbrücke zum merken und ich umarm dich nicht nur sondern knutsch dich noch ab.
                  Nee im Ernst, vielen Dank!

                  Gruß
                  dem geholfenen
                  T-Rex

                  1. Tach!

                    Jetzt noch eine Eselsbrücke zum merken und ich umarm dich nicht nur sondern knutsch dich noch ab.

                    Die Eselsbrücke ist die Reihenfolge, in der die Klauseln notiert werden (müssen). Nur SELECT tanzt aus der Reihe.

                    dedlfix.

                    1. Die Eselsbrücke ist die Reihenfolge, in der die Klauseln notiert werden (müssen). Nur SELECT tanzt aus der Reihe.

                      Ja nee hab ich schon gemerkt ;). Bekommst trotzdem nochmal fachlich hilfreich von mir !!!

                      Gruß
                      Tanzender-Rex

                  2. Om nah hoo pez nyeetz, T-Rex!

                    Jetzt noch eine Eselsbrücke zum merken und ich umarm dich nicht nur sondern knutsch dich noch ab.

                    Freundliche Junggesellen wohnen gern schon heimlich ohne Liebhaber.
                    Fast jeder weiß genau, Schafe hampfeln ordentlich Löwenzahn.

                    Matthias

                    --
                    Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Ventil und Ventilator.