Heike: Zwei Ergebnisse verbinden

Hi,
irgendwie habe ich gerade ein Brett vorm Kopf. Ich habe ein Problem aus einer Tabelle das gewünschte Ergebnis zu bekommen. Ein UNION wäre schön, aber leider mit  MySQL nicht zu machen. Hier eine Verdeutlichung des Problems:

Aus dieser Tabelle
-----+----------
id   | farbe
-----+----------
12   | rot
15   | rot
12   | blau
13   | blau
15   | grün

möchte ich alle ids haben, die rot und blau sind!

Für ein wenig erhellendes Licht wäre ich sehr dankbar ;-)

Grüße
Heike

  1. Hi Heike,

    Aus dieser Tabelle
    -----+----------
    id   | farbe
    -----+----------
    12   | rot
    15   | rot
    12   | blau
    13   | blau
    15   | grün

    möchte ich alle ids haben, die rot und blau sind!

    Wozu union?
    SELECT id FROM tablename WHERE farbe='blau' AND farbe='rot'

    enspricht: 12,15,12,13

    Übrigens sollten keine gleichen ID's vorkommen (kann natürlich auch nur ein Schreibfehler sein ;)

    meintest Du das?

    ciao
    romy

    --
    DIE ROMY AUS L. AN DER P. SAGT DANKE UND AUF WIEDERSEHEN
    ->Alles ist gut wenn es aus Schokolade ist
    1. Hi Romy,

      Wozu union?
      SELECT id FROM tablename WHERE farbe='blau' AND farbe='rot'

      enspricht: 12,15,12,13

      Dem ist leider nicht so, da es keinen Eintrag in der Tabelle gibt der dem entsprechen kann.
      Außerdem darf nur die id 12 als Ergbnis kommen, da nur sie rot und blau ist!

      Aber Danke trotzdem!
      Grüße
      Heike

      1. Hi Heike,

        SELECT id FROM tablename WHERE farbe='blau' AND farbe='rot'
        enspricht: 12,15,12,13

        Dem ist leider nicht so, da es keinen Eintrag in der Tabelle gibt der dem entsprechen kann.

        ? den Satz verstehe ich nicht

        Außerdem darf nur die id 12 als Ergbnis kommen, da nur sie rot und blau ist!

        dem kann man aus dem Weg gehen

        SELECT id FROM tablename WHERE farbe='blau' OR farbe='rot' AND NOT EXISTS (SELECT id FROM tablename WHERE farbe='blau' AND farbe='rot')

        das sollte 15 und 13 bringen und 12 auslassen

        ciao
        romy

        --
        DIE ROMY AUS L. AN DER P. SAGT DANKE UND AUF WIEDERSEHEN
        ->Alles ist gut wenn es aus Schokolade ist
        1. Moin Moin !

          Hi Heike,

          SELECT id FROM tablename WHERE farbe='blau' AND farbe='rot'
          enspricht: 12,15,12,13

          Dem ist leider nicht so, da es keinen Eintrag in der Tabelle gibt der dem entsprechen kann.
          ? den Satz verstehe ich nicht

          SQL arbeitet zeilenweise. Auf keine einzige Zeile treffen die Aussage farbe='rot' und farbe='blau' gleichzeitig zu. Wäre auch etwas merkwürdig. Zugegeben, ich mußte auch erstmal wieder drüber nachdenken.

          Außerdem darf nur die id 12 als Ergbnis kommen, da nur sie rot und blau ist!

          Die Begründung mußte lauten: da nur für 12 sowohl eine Zeile mit der Farbe rot als auch eine Zeile mit der Farbe blau existiert.

          dem kann man aus dem Weg gehen

          SELECT id FROM tablename WHERE farbe='blau' OR farbe='rot' AND NOT EXISTS (SELECT id FROM tablename WHERE farbe='blau' AND farbe='rot')

          das sollte 15 und 13 bringen und 12 auslassen

          Nein, das innere SELECT liefert immer eine leere Menge, damit liefert das äußere SELECT alle Einträge, die entweder rot oder blau sind.

          Ich denke, es müßte irgendwie über GROUP BY, COUNT und/oder HAVING gehen, aber darüber müßte ich nochmal 'ne Runde meditieren.

          Alexander

          --
          Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so!"
          1. Moin Moin !

            Wie wäre das:

            SELECT
              id,COUNT(*) AS n
            FROM
              tabelle
            WHERE
              farbe='rot' OR farbe='blau'
            GROUP BY
              id
            HAVING
              n > 1            <---- evtl. auch COUNT(*) statt n

            Alexander

            --
            Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so!"
            1. Moin Moin !

              SELECT
                id,COUNT(*) AS n
              FROM
                tabelle
              WHERE
                farbe='rot' OR farbe='blau'
              GROUP BY
                id,farbe
              HAVING
                n > 1            <---- evtl. auch COUNT(*) statt n

              Und so sollte es mit mehreren identischen Paaren auch noch funktionieren.

              Alexander

              --
              Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so!"
              1. Moin Moin !

                Moin

                SELECT
                  id,COUNT(*) AS n
                FROM
                  tabelle
                WHERE
                  farbe='rot' OR farbe='blau'
                GROUP BY
                  id,farbe
                HAVING
                  n > 1            <---- evtl. auch COUNT(*) statt n

                Und so sollte es mit mehreren identischen Paaren auch noch funktionieren.

                Du hast natürlich recht mit dem Zeilenweise arbeiten.
                allerdings verstehe ich hierbei die letzte Klausel mit dem Having nicht wirklich. Erklär mir es mal bitte!

                ciao
                romy

                --
                DIE ROMY AUS L. AN DER P. SAGT DANKE UND AUF WIEDERSEHEN
                ->Alles ist gut wenn es aus Schokolade ist
                1. Moin Moin !

                  SELECT
                    id,COUNT(*) AS n
                  FROM
                    tabelle
                  WHERE
                    farbe='rot' OR farbe='blau'
                  GROUP BY
                    id,farbe
                  HAVING
                    n > 1            <---- evtl. auch COUNT(*) statt n

                  Und so sollte es mit mehreren identischen Paaren auch noch funktionieren.

                  Du hast natürlich recht mit dem Zeilenweise arbeiten.
                  allerdings verstehe ich hierbei die letzte Klausel mit dem Having nicht wirklich. Erklär mir es mal bitte!

                  Erstmal: das GROUP BY muß nur "id" heißen, nicht "id,farbe", sonst geht's doch nicht. :-(

                  ----+----------
                  id  | farbe
                  ----+----------
                  12  | rot
                  15  | rot
                  12  | blau
                  13  | blau
                  15  | grün

                  HAVING funktioniert wie WHERE, nur ist HAVING von der (normalerweise stattfindenden) Query-Optimierung ausgenommen und filtert erst unmittelbar vor der Rückgabe des Ergebnisses.

                  Das ganze Statement gruppiert [ GROUP BY ] erstmal nach "id", zählt [ COUNT(*) ] für jede id die Zeilen der Gruppe, und das alles nur für Zeilen, die rot oder blau sind. Ohne das having bekommst Du also sowas:

                  id | n
                  ---+---
                  12 | 2   <-- je eine rot und blau
                  15 | 1   <-- nur die rote zählt, die grüne hat WHERE rausgeworfen
                  13 | 1   <-- eine blaue

                  Und HAVING sucht jetzt alle, die mehr als eine Zeile (n>1) haben.

                  id | n
                  ---+---
                  12 | 2

                  q.e.d.

                  Auf die Nase fällt das ganze, wenn in der Original-Tabelle Paare doppelt vorkommen, weil die bei COUNT(*) eben auch doppelt zählen.

                  Verstanden ?

                  Alexander

                  --
                  Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so!"
                  1. Hi,

                    Verstanden ?

                    ja ich denke schon, wollte schon immer mal wissen, was es mit dem HAVING auf sich hat.

                    danke
                    ciao
                    romy

                    --
                    DIE ROMY AUS L. AN DER P. SAGT DANKE UND AUF WIEDERSEHEN
                    ->Alles ist gut wenn es aus Schokolade ist
              2. Hi!

                Vielen, vielen Dank für die Lösungsvorschläge. Natürlich kommt zu dem Ganzen noch dazu, dass es auch mehr als 2 Suchkriterien sein könnten, die auch noch mit UND, OR oder NOT verbunden sein können.
                Ich werde es wohl jetzt so lösen:
                In eine temporäre Tabelle (felder= id, counter) werden alle IDs geschrieben. Dann wird der Counter für jede Suchabfrage hochgezählt, so dass auch eine Frage nach: (rot und blau) oder (rot und gelb) ausgewertet werden kann.

                Nochmal Danke an Euch alle! Das Forum ist immer eine gute Inspiration!

                Grüße
                Heike

    2. Aus dieser Tabelle
      -----+----------
      id   | farbe
      -----+----------
      12   | rot
      15   | rot
      12   | blau
      13   | blau
      15   | grün

      Übrigens sollten keine gleichen ID's vorkommen (kann natürlich auch nur ein Schreibfehler sein ;)

      oder eine Koppeltabelle ;o)

  2. Hi,
    irgendwie habe ich gerade ein Brett vorm Kopf. Ich habe ein Problem aus einer Tabelle das gewünschte Ergebnis zu bekommen. Ein UNION wäre schön, aber leider mit  MySQL nicht zu machen. Hier eine Verdeutlichung des Problems:

    Aus dieser Tabelle
    -----+----------
    id   | farbe
    -----+----------
    12   | rot
    15   | rot
    12   | blau
    13   | blau
    15   | grün

    möchte ich alle ids haben, die rot und blau sind!

    Für ein wenig erhellendes Licht wäre ich sehr dankbar ;-)

    SELECT id FROM tablename WHERE farbe='blau' AND id IN (select id from tabelle where farbe = 'rot')... geht sowas???

    gruss
    horst

    1. Hi,
      irgendwie habe ich gerade ein Brett vorm Kopf. Ich habe ein Problem aus einer Tabelle das gewünschte Ergebnis zu bekommen. Ein UNION wäre schön, aber leider mit  MySQL nicht zu machen. Hier eine Verdeutlichung des Problems:

      Aus dieser Tabelle
      -----+----------
      id   | farbe
      -----+----------
      12   | rot
      15   | rot
      12   | blau
      13   | blau
      15   | grün

      möchte ich alle ids haben, die rot und blau sind!

      Für ein wenig erhellendes Licht wäre ich sehr dankbar ;-)

      SELECT id FROM tablename WHERE farbe='blau' AND id IN (select id from tabelle where farbe = 'rot')... geht sowas???

      oder sowas:
      select a.id, b.id from tabelle AS a, tabelle AS b where a.id = b.id and a.farbe = blau and b.farbe = rot.... oder so was in der art. kann es leider nicht testen

      http://www.mysql.de/documentation/mysql/bychapter/manual.de_Reference.html#SELECT gibts auch beispiele, vielleicht auch eines was auf dein problem passt

      gruss
      horst

    2. Hi horst,

      SELECT id FROM tablename WHERE farbe='blau' AND id IN (select id from tabelle where farbe = 'rot')... geht sowas???

      mySQL kann ggf. noch keine Subselects.

      Viele Grüße
            Michael

      --
      T'Pol: I apologize if I acted inappropriately.
      V'Lar: Not at all. In fact, your bluntness made me reconsider some of my positions. Much as it has now.
  3. Hi Heike,

    Aus dieser Tabelle
    -----+----------
    id   | farbe
    -----+----------
    12   | rot
    15   | rot
    12   | blau
    13   | blau
    15   | grün
    möchte ich alle ids haben, die rot und blau sind!
    Für ein wenig erhellendes Licht wäre ich sehr dankbar ;-)

    ich würde an die Sache mit einem JOIN der Tabelle gegen sich selbst heran gehen, also etwa:

    select a.id from t as a, t as b where a.farbe='rot' and b.farbe='blau' and a.id=b.id;

    Die Idee ist, daß der JOIN eine temporäre Tabelle erzeugt, welche vier Spalten hat: a.id, b.id, a.farbe und b.farbe. Schlimmstenfalls hast Du bei 5 Einträgen dann 25 Zeilen in dieser Tabelle; wenn der Query Optimizer die WHERE-Klausel in der angegebenen Reihenfolge auswertet (also zuerst projeziert und dann ausmultipliziert), dann sind es in Deinem Fall noch 4 (nämlich [a.id,b.id] = [12,12], [12,13], [15,12] und [15,12]). Letzeres könntest Du ggf. durch Indexe auf der "farbe"-Spalte fördern - dann machst Du es dem RDBMS leichter, die entsprechenden Teilmengen effizient zu berechnen.
    Von diesen Zeilen sucht er dann diejenigen aus, bei denen die beiden ids übereinstimmen - das ist dann nur noch eine einzige Zeile [12,12]. Und von dieser wählt die SELECT-Klausel zuletzt die erste Spalte aus (die zweite hätte es natürlich auch getan) - that's it.

    Ich bin mir nicht sicher, ob die GROUP-BY-Methode von Alexander nicht doch performanter ist. Mein Ansatz ist allerdings der universellere, denke ich.

    Außerdem läßt sich mein JOIN sicherlich irgendwie kürzer schreiben (INNER JOIN? Jedenfalls kann man das "a.id=b.id" irgendwie impliziter ausdrücken).

    Viele Grüße
          Michael

    --
    T'Pol: I apologize if I acted inappropriately.
    V'Lar: Not at all. In fact, your bluntness made me reconsider some of my positions. Much as it has now.