AllesMeins: MySQL: JOIN - Datensätze einzeln counten

Hi,

folgendes Problem. Ich habe zwei Tabellen a und b die ich per LEFT JOIN verknüpfe. Nun würde ich gerne Informationen über die Anzahl der gefundenen Datensätze ermitteln.

Beispiel:

Tabelle a:

ID|Name
----------
01|Name1
02|Name2
03|Name3
04|NULL
05|Name4

Tabelle b:

ID|Untergruppe
----------
01|Untergruppe1
01|Untergruppe2
01|Untergruppe3
02|Untergruppe1
03|Untergruppe1
04|Untergruppe1
05|Untergruppe1

Query:

... LEFT JOIN b ON a.id = b.id ...

Mein Problem: Wenn ich ein count(a.name) mache, dann zählt MySQL verständlicherweise "Name1" 3 mal, da er ja in 3 Zeilen der gejointen "Tabelle" vorkommt. Sprich ein count(a.name) ergibt in dem Beispiel 6. Nun hätte ich aber gerne die "reinen" Zahlen. Also die Zahl wieviele Namen es in Tabelle a wirklich gibt (so als wären die Tabellen nicht gejoint). Ist das irgendwie Möglich ohne die Abfrage in zwei Querys zu zerlegen?

Grüße

Marc

  1. Hallo,

    vielleicht könnte Count(Distinct feldname) Dein Freund sein.

    http://dev.mysql.com/doc/refman/4.1/en/group-by-functions.html

    Gruß
    Olaf

    1. Hi,

      leider nicht. Ich kann nicht sicherstellen das die Namen immer verschieden sind. Und so wie ich das verstehe zählt der ja nur verschiedene Werte, nicht wahr?

      Marc

      1. Hallo,

        leider nicht. Ich kann nicht sicherstellen das die Namen immer verschieden sind. Und so wie ich das verstehe zählt der ja nur verschiedene Werte, nicht wahr?

        Warum nimmst Du dann statt a.name nicht a.id? Gib am besten einmal Deine gesamte Query an, damit klar ist, was diese noch an Daten liefern soll.

        Marc

        Gruß
        Olaf

        1. Hi,

          den Query bin ich ja gerade noch am bauen ;)
          Und die Tabelle ist natürlich auch etwas komplizierter als in meinem Mini-Beispiel.
          Aber ich versuche mal zu beschreiben, was ich erreichen will. Es geht um einen Datenbankexport über mehrere Tabellen. Tabelle a enthält Bücher und Tabelle b enthält die dazugehörigen Kapitel. Nun möchte ich vor dem eigenen Export dem Nutzer sagen was ihn erwartet. Also etwa in der Art:

          Für ihre Anfrage wurden 25 Bücher gefunden. Bei 17 dieser Bücher ist ein Autor eingetragen, bei 8 eine Titel usw.
          In den 25 Büchern wurden insgesamt 75 Kapitel gefunden. 23 der Kapiteldatensätze enthalten einen Wert beim feld XYZ, 17 einen beim feld ZYX usw...

          Und da bringt es mir natürlich gar nichts, wenn die Abteilungs-Datensätze alle mehrfach gezählt werden.

          Grüße

          Marc

          1. Hallo Marc,

            Für ihre Anfrage wurden 25 Bücher gefunden. Bei 17 dieser Bücher ist ein Autor eingetragen, bei 8 eine Titel usw.
            In den 25 Büchern wurden insgesamt 75 Kapitel gefunden. 23 der Kapiteldatensätze enthalten einen Wert beim feld XYZ, 17 einen beim feld ZYX usw...

            ich würde persönlich mehrere Queries benutzen und die Ergebnisse in Funktionsaufrufe binden (Pseudocode):

            function getNumberOfBooks() {
                if this.numberOfBooks is undefined {
                    this.executeQuery_ABC()
                }
                return this.numberOfBooks
            }

            function executeQuery_ABC() {
                query = 'SELECT ...'
                result = execute query
                this.numberOfBooks = result[numberOfBooks]
                this.numberOfChapters = result[numberOfChapters]
            }

            Wenn Du diese „faule Dateninitalisierung“ benutzt, kannst Du später immer noch einen mächtigeren Queryaufruf starten, der Dir eben mehr Werte zurückgibt und somit andere Queries unnötig macht.

            Gruß
            Olaf

            1. Hi,

              hab leider erst jetzt wieder Zeit gefunden mich damit zu beschäftigen. Dabei ist mir aufgefallen das sich auch das zerlegen in zwei Querys gar nicht so einfach gestaltet, da es sein kann das Inhalte der Tabelle Kapitel die Ergebnisse bei den Büchern beeinflussen.

              Also Beispiel ich will alle Bücher haben, bei denen es eine Kapitel mit der Nummer 7 gibt. Und um das zu ermitteln müsste ich ja eigentlich wieder Joinen, oder übersehe ich da gerade was?

              Grüße

              Marc

  2. yo,

    ich beziehe mich unter anderem auf deine aussagen weiter unten. aber zuerst stellt sich die fragen, ob es den ein outer join sein muss oder ob nicht jedes buch auch immer mindestens ein kapitel hat. somit wäre eine inner join die richtige wahl.

    was das problem mit den zählen angeht, so sollte es in einer querry gehen. was du brauchst ist die aggregatfunktion COUNT(), ein DISTINCT über spalten der buchtabelle, die funktion instr und den IF Operator zur verzweigung.

    ich bin gerade auf den sprung zur arbeit, habe also wenig zeit. ich gebe deswegen nur mal das grundprinzip an:

    In den 25 Büchern

    COUNT(DISTINCT buchname)

    wurden insgesamt 75 Kapitel gefunden.

    COUNT(*)

    23 der Kapiteldatensätze enthalten einen Wert beim feld XYZ,

    COUNT(IF(INSTR(xyz, 'wert'),1,0))

    17 einen beim feld ZYX usw...

    COUNT(IF(INSTR(zyx, 'wert'),1,0))

    so, muss nun schnell zur arbeit.....

    Ilja

    1. Hi,

      COUNT(DISTINCT buchname)

      Leider nicht, da nicht sicher gestellt ist das alle Einträge unterschiedliche Namen haben.

      COUNT(IF(INSTR(xyz, 'wert'),1,0))

      Da hab ich mich wohl ungünstig ausgedrückt. Ich meinte nicht Feld XYZ hat den Wert "Wert", sondern hat überhaupt einen Wert (also ungleich NULL)

      Grüße

      Marc