Christian: [mysql5] Kartesisches Produkt eingrenzen

Hallihallo,

ich habe:

2 Tabellen:

A - id(primkey), name
B - nicht_unique_Spalte_mit_ids_aus_A (u.A.)

Ich will jetzt diejenigen A.id, A.name haben, wo A.id = B.id ist, also nur diejenigen Datensätze aus A, deren ID mindestens 1 mal in B als (nicht schlüssel-)attribut eingetragen ist.

SELECT A.id, A.name FROM A,B WHERE A.id = B.nicht_unique_Spalte_mit_ids_aus_A

liefert mir nun:

1 name1
1 name1
1 name1
2 name2
2 name2

ich wollte aber lediglich:

1 name1
2 name2

Klar, kommt durch die Bildung des Kartesischen Produkts, denn A.id taucht u.U. mehrmals in B.nicht_unique_Spalte_mit_ids_aus_A auf.

Tja. Und watt nu?
Kann man vllt. irgendwie einschränken, dass die Einträge dieser 'imaginären' Ergebnis-Tabelle unique sein müssen?

Schöne Grüße aus Münster
Christian

  1. Hallo!

    liefert mir nun:

    1 name1
    1 name1
    1 name1
    2 name2
    2 name2

    ich wollte aber lediglich:

    1 name1
    2 name2

    Klar, kommt durch die Bildung des Kartesischen Produkts, denn A.id taucht u.U. mehrmals in B.nicht_unique_Spalte_mit_ids_aus_A auf.

    Das sieht das ganz schwer nach einem GROUP BY aus.

    SELECT A.id, A.name FROM A,B WHERE A.id = B.nicht_unique_Spalte_mit_ids_aus_A GROUP BY A.id, A.name

    André Laugks

    --
    Die Frau geht, die Hilti bleibt!
    1. Moin!

      Das sieht das ganz schwer nach einem GROUP BY aus.

      Nein, nach einem SELECT DISTINCT.

      - Sven Rautenberg

      --
      "Love your nation - respect the others."
      1. yo,

        Das sieht das ganz schwer nach einem GROUP BY aus.

        Nein, nach einem SELECT DISTINCT.

        mal davon abgesehen, dass es sich hier nicht um das kartesische produkt handelt, da eine join anweisung vorhanden ist, ist in diesem falle die abfrage mit GROUP BY oder DISTINCT genau das gleiche.

        Ilja

        1. Hallo,

          mal davon abgesehen, dass es sich hier nicht um das kartesische produkt handelt, da eine join anweisung vorhanden ist, ist in diesem falle die abfrage mit GROUP BY oder DISTINCT genau das gleiche.

          Wobei mir die GROUP BY-Variante insofern besser gefällt, da sie die Absichten des Autors besser zur geltung bringt. Will heissen, dass DISTINCT eher nach zufälligen Ergebnissen 'riecht' während bei einer ausformulierten GROUP BY-Klausel es eher so scheint, dass sich schon jemand Gedanken darüber gemacht hat, was da an Ergebnissen kommen sollte (Wobei auch hier jemand ohne Hirn und Verstand zu Werke gegangen sein kann *g*).

          Kurz: Ich mag DISTINCT in einem Produktionssystem nicht.

          Grüße
            Klaus

          1. Hallo,

            danke an alle (antworter) für die antworten!

            Grüße
            Christian

          2. Hallo !

            mal davon abgesehen, dass es sich hier nicht um das kartesische produkt handelt,
            [...]

            Dann waeren's naemlich 10 Ergenissaetze wenn ich dass richtig sehe

            [...]
            da eine join anweisung vorhanden ist,
            ist in diesem falle die abfrage mit GROUP BY oder DISTINCT genau das gleiche.
            [...]

            Liegt das nicht eher daran, dass in dem SELECT nur Felder der unabhaengigen Tablle stehen ?

            Wenn namlich auch noch 'name' oder irgendwas von der zweiten Tabelle B selektiert wuerde, wurde DISTINCT nicht mehr weiterhelfen.
            Dann muesste man meines Erachtens sogar

            GROUP BY A.id, A.name

            verwenden.

            Hingegen wuerde auch ein echtes Kreuzprodukt durch DISTINCT (wenn nur aus A ) oder GROUP BY eingeschraenkt, oder ?

            [...]
            Kurz: Ich mag DISTINCT in einem Produktionssystem nicht.
            [...]

            Wenn man's ganz genau nimmt koennte man zudem noch

            ORDER BY NULL

            • wie in der MySQL Doku empfohlen - in Erwaegung ziehen,
              wenn man keine Sortierung braucht. GROUP BY ( und DISTINCT, was implizit GROUP BY verwendet ) sortiert naemlich hier implizit mit. Da ein String-Feld mit drin ist , koennte das evtl teuer werden- wie teuer haengt davon ab ob das Feld indiziert ist.

            Gruss

            Holger

            1. yo,

              Dann waeren's naemlich 10 Ergenissaetze wenn ich dass richtig sehe

              das kommt drauf an, wieviele daten sich in den beiden tabellen befinden. die anzahl der datensätze der beiden tabllen miteinander multipliziert ergibt die summe des ergebnisses eines kreuzproduktes (jeder mit jedem).

              Liegt das nicht eher daran, dass in dem SELECT nur Felder der unabhaengigen Tablle stehen ?

              nein, es liegt daran, dass die spaltenausgaben bei DISTINCT genau den spalten entspricht, über die du auch gruppieren würdest. und dabei ist es egal, aus welcher tabelle die spalten kommen.

              GROUP BY ( und DISTINCT, was implizit GROUP BY verwendet ) sortiert naemlich hier implizit mit. Da ein String-Feld mit drin ist , koennte das evtl teuer werden- wie teuer haengt davon ab ob das Feld indiziert ist.

              jede GROUP BY oder DISTINCT Anweisung sind letztlich nur sortierungen. insofern ist impliziet das falsche wort, weil es so gewollt ist.

              Ilja

              1. Hallo !

                das kommt drauf an, wieviele daten sich in den beiden tabellen befinden.

                Ach was !

                die anzahl der datensätze der beiden tabllen miteinander multipliziert ergibt die summe des ergebnisses eines kreuzproduktes (jeder mit jedem).

                Potzblitz !

                Na dann 'lass uns mal sehen :

                2 Datensaetze sind in A

                A#1 wird auf 3 Saetze auf B abgebildet.
                A#2 auf 2 Saetze aus B.

                => 5 Saetze in B, denn wen sollten die restlichen B-Datensaetze wohl referenzieren ?

                ( + ? mit NULL FK's aber in Anbetracht der Benennung der
                FK - Feldes gehe ich davon aus, dass es NOT NULL ist )

                => 2*5 = 10 beim kartesischen Produkt.

                Hatte ich nicht genau das geschrieben ?

                Liegt das nicht eher daran, dass in dem SELECT nur Felder der unabhaengigen Tablle stehen ?

                nein, es liegt daran, dass die spaltenausgaben bei DISTINCT genau den spalten entspricht, über die du auch gruppieren würdest.

                Ja, namelich alle aus A, der unabhaengigen Tabelle der Relation. Was ich ja bereits geschrieben hatte.

                und dabei ist es egal, aus welcher tabelle die spalten kommen.

                Das stimmt nicht. Wenn aus B, wovon man ausgehen muss, verschiedene B-Werte for einen  A-Datensatz mitselektiert wuerden, waeren die Rows ggf. DISTINCT auch wenn A.id und A.name doppelt auftraeten.

                GROUP BY ( und DISTINCT, was implizit GROUP BY verwendet ) sortiert naemlich hier implizit mit. Da ein String-Feld mit drin ist , koennte das evtl teuer werden- wie teuer haengt davon ab ob das Feld indiziert ist.

                jede GROUP BY oder DISTINCT Anweisung sind letztlich nur sortierungen.

                Stimmt nicht. Zum Suchen brauch ich n, zum Sortieren n*log(n) Operationen. Auch in der Doku steht was zum diesbezueglichen
                Overhead.

                Gute Nacht !

                Holger

                1. yo,

                  => 2*5 = 10 beim kartesischen Produkt.

                  Hatte ich nicht genau das geschrieben ?

                  nein, du bist davon ausgegangen, dass sich in der einen zwei und in der anderen fünf datensätze aufgrund einer JOIN anweisung befinden. ich würde diesen schluss nicht ziehen, da es sich um einen INNER JOIN und nicht um einen FULL OUTER JOIN handelt. es können sowohl in Tabelle A als auch in Tabelle B datensätze vorhanden sein, die der INNER JOIN nicht greift.

                  und dabei ist es egal, aus welcher tabelle die spalten kommen.

                  Das stimmt nicht. Wenn aus B, wovon man ausgehen muss, verschiedene B-Werte for einen  A-Datensatz mitselektiert wuerden, waeren die Rows ggf. DISTINCT auch wenn A.id und A.name doppelt auftraeten.

                  hast du es schon mal ausprobiert, dass du mit einem DISTINCT und der ausgabe über die gleichen Spalten wie bei einem GROUP BY unterschiedliche ergebnisse rauskommen ? wie gesagt, es spielt keine rolle, aus welcher tabelle die spalten kommen. warum auch, weder DISTINCT noch GROUP BY sind so implementiert, dass es eine rolle spielen könnte.

                  jede GROUP BY oder DISTINCT Anweisung sind letztlich nur sortierungen.

                  Stimmt nicht. Zum Suchen brauch ich n, zum Sortieren n*log(n) Operationen. Auch in der Doku steht was zum diesbezueglichen

                  erstens reden wir nicht über suchen, sondern über sortieren. und zweitens zitiere ich einfach mal von der seite, die du angegeben hast:

                  "If you use GROUP BY, output rows are sorted according to the GROUP BY columns as if you had an ORDER BY for the same columns"

                  klingt doch sehr nach sortieren oder nicht ?

                  Ilja

                  1. Hallo !

                    [...]
                    es können sowohl in Tabelle A als auch in Tabelle B datensätze vorhanden sein, die der INNER JOIN nicht greift.

                    Da hast Du recht, nicht =, sondern  >=10.

                    hast du es schon mal ausprobiert, dass du mit einem DISTINCT und der ausgabe über die gleichen Spalten wie bei einem GROUP BY unterschiedliche ergebnisse rauskommen ?

                    Ja, ich habe schon mal mit Datenbanken zu tun gehabt.
                    ;-)

                    wie gesagt, es spielt keine rolle, aus welcher tabelle die spalten kommen. warum auch, weder DISTINCT noch GROUP BY sind so implementiert, dass es eine rolle spielen könnte.

                    Bei einem DISTINCT haettest Du aber gar nicht die syntaktischen Moeglichkeiten.

                    [...]
                    "If you use GROUP BY, output rows are sorted according to the GROUP BY columns as if you had an ORDER BY for the same columns"

                    Aber der Absatz geht noch etwas weiter (a.a.O.)
                    "To avoid the overhead of sorting that GROUP BY produces, add ORDER BY NULL:"

                    Das Problem an Deinem ersten Posting war aber gar nicht die Mengenlehre sondern eher die
                    Art das zu kommunizieren.

                    Gruss

                    Holger