Kalle_B: COUNT- Problem

Hallöle,

Eine Abfrage gibt Personen aus, die einer Gruppe angehören können:

gruppe_id  person_id
---------  ---------
0          4711
1          4712
1          4713
1          4714
0          4716

Nun möchte ich eine Gruppe nur als 1 Vorkommen zählen. Für obiges Beispiel soll anz_kontakte also 3 sein.

SELECT
 per1.id
,per1.bezeichnung
,per1.textfarbe
,per1.wichtig
,per1.adr_unt
,per1.ort
,per1.vname
,per1.nname
,count(kon1.id) anz_kontakte
FROM     ".$db[0]['personen']." AS per1

LEFT JOIN ".$db[0]['kontakte']." AS kon1
ON        kon1.aussteller_id = per1.id
AND      (kon1.prio_1=1 OR kon1.prio_2=1)

WHERE     per1.owner_id=".$owner_id."
AND       per1.adr_kz = ".$arr['aus_bes']."
".$and."
GROUP BY per1.bezeichnung, per1.ort, per1.adr_unt

Im Moment ist anz_kontakte = 5

Lieben Gruß, Kalle

  1. Hallöle,

    Eine Abfrage gibt Personen aus, die einer Gruppe angehören können:

    gruppe_id  person_id
    ---------  ---------
    0          4711
    1          4712
    1          4713
    1          4714
    0          4716

    Nun möchte ich eine Gruppe nur als 1 Vorkommen zählen. Für obiges Beispiel soll anz_kontakte also 3 sein.

    [...]

    Hast Du mal ein GROUUP BY gruppe_id oder ggf. ein DISTINCT probiert?

    Nick

    --
    --------------------------------------------------
    http://www.xilp.eu
    XILP Internet Links People
    Dein persoenliches privates Netzwerk
    aus Freunden, Verwandten, Bekannten und Kollegen.
    --------------------------------------------------
  2. Hallo Kalle,

    SELECT
    per1.id
    ,per1.bezeichnung
    ,per1.textfarbe
    ,per1.wichtig
    ,per1.adr_unt
    ,per1.ort
    ,per1.vname
    ,per1.nname
    ,count(kon1.id) anz_kontakte
    FROM     ".$db[0]['personen']." AS per1

    LEFT JOIN ".$db[0]['kontakte']." AS kon1
    ON        kon1.aussteller_id = per1.id
    AND      (kon1.prio_1=1 OR kon1.prio_2=1)

    WHERE     per1.owner_id=".$owner_id."
    AND       per1.adr_kz = ".$arr['aus_bes']."
    ".$and."
    GROUP BY per1.bezeichnung, per1.ort, per1.adr_unt

    sowas schluckt nur MySQL. Und das Ergebnis ist anders als das, das Du haben möchtest. Du könntest mit Subselects arbeiten.

    Denke daran, dass Du beim Einsatz von Aggregatsfunktionen nach _allen_
    Spalten gruppieren musst, auf die _keine_ Aggregatsfunktion angewandt wird.

    Bei MySQL 5.x könntest Du eventuell auch mit einem View arbeiten, wobei Du
    EXPLAIN befragen solltest, was performanter ist.

    Freundliche Grüße

    Vinzenz

  3. Eine Abfrage gibt Personen aus, die einer Gruppe angehören können:

    gruppe_id  person_id
    ---------  ---------
    0          4711
    1          4712
    1          4713
    1          4714
    0          4716

    Nun möchte ich eine Gruppe nur als 1 Vorkommen zählen. Für obiges Beispiel soll anz_kontakte also 3 sein.

    Das Beispiel reicht nicht aus. Was genau wünscht der Herr?

    SELECT
    per1.id
    ,per1.bezeichnung
    ,per1.textfarbe
    ,per1.wichtig
    ,per1.adr_unt
    ,per1.ort
    ,per1.vname
    ,per1.nname
    ,count(kon1.id) anz_kontakte
    FROM     ".$db[0]['personen']." AS per1

    LEFT JOIN ".$db[0]['kontakte']." AS kon1
    ON        kon1.aussteller_id = per1.id
    AND      (kon1.prio_1=1 OR kon1.prio_2=1)

    WHERE     per1.owner_id=".$owner_id."
    AND       per1.adr_kz = ".$arr['aus_bes']."
    ".$and."
    GROUP BY per1.bezeichnung, per1.ort, per1.adr_unt

    1.) GROUP BY-Datenfelder sollten denen unter SELECT entsprechen
    2.) Es ist besser das tatsächlich versandte SQL zu posten
    3.) Was hast Du genau versucht und was klappt nicht?

    1. Nun möchte ich eine Gruppe nur als 1 Vorkommen zählen.

      Das Beispiel reicht nicht aus.

      n. VERSUCH mit IF: Wenn gruppe_id, dann person_id=0. So bekomme ich diese Auswahl:

      gruppe_id  besucher_id
      ---------  -----------
      0          4711
      1          0
      1          0
      1          0
      0          4716

      SELECT
       per1.id           adr_id
      ,per1.bezeichnung
      ,per1.textfarbe
      ,per1.wichtig
      ,per1.adr_unt
      ,per1.ort
      ,per1.vname
      ,per1.nname
      ,kon1.gruppen_id                              gruppen_id
      ,IF(kon1.gruppen_id=0 , kon1.besucher_id, 0)  besucher_id
      FROM     tm_adressen AS per1

      LEFT JOIN tm_kontakte AS kon1
      ON        kon1.aussteller_id = per1.id
      AND      (kon1.prio_1=1 OR kon1.prio_2=1)

      WHERE     per1.owner_id=4
      AND       per1.adr_kz = 1
      AND adr_unt=1
      ORDER BY per1.bezeichnung, per1.ort, per1.adr_unt, gruppen_id, besucher_id

      COUNT( DISTINCT( gruppen_id, besucher_id ))

      wäre mein Ergebnis. Aber dieses Konstrukt ist nicht zulässig.

      Fehlermeldung: "1241: Operand should contain 1 column(s)"

      1. yo,

        den beitrag von Vinzenz lesen, versuchen zu verstehen, was er sagt und erst dann handeln. alles andere hat keinen sinn und führt nur in die falsche richtung.

        Ilja

      2. Ich möchte ich einen Wert mit IF beeinflussen und DANACH zählen. Geht das?

        SELECT
        ...
        ,IF(kon1.gruppen_id=0 , NULL, kon1.gruppen_id)   gruppen_id
        ,IF(kon1.gruppen_id>0 , NULL, kon1.besucher_id)  besucher_id
        ,COUNT(DISTINCT gruppen_id)                      anz_gruppen
        ,COUNT(DISTINCT besucher_id)                     anz_einzel

        So geht es nicht.

        Bei Gruppen wird fast korrekt gezählt, die Gruppe 0 ist allerdings auch dabei. Soll sie nicht.

        Und bei Einzelbesuchern werden alle Besucher gezählt, auch die in den Gruppen.

        Die IF- Bedingung hat also keinen Einfluss auf die Zählung.

        Kalle

        1. Das isses:

          SELECT
          ...
          ,COUNT(DISTINCT IF(kon1.gruppen_id=0 , NULL, kon1.gruppen_id))  anz_gruppen
          ,COUNT(DISTINCT IF(kon1.gruppen_id>0 , NULL, kon1.besucher_id)) anz_einzel

          Kalle

  4. Hallo Kalle,

    auch wenn Du es zu haben glaubst, etwas detailliertere Vorschläge:

    Eine Abfrage gibt Personen aus, die einer Gruppe angehören können:

    gruppe_id  person_id
    ---------  ---------
    0          4711
    1          4712
    1          4713
    1          4714
    0          4716

    SELECT  
        gruppe_id,  
        COUNT(gruppe_id) AS anzahl  
    GROUP BY gruppe_id  
    
    

    liefert Dir

    gruppe_id anzahl
          0      2
          1      3

    Mit

    CREATE VIEW vw_gruppen_verteilung AS  
    SELECT  
        gruppe_id,  
        COUNT(gruppe_id) AS anzahl  
    GROUP BY gruppe_id
    

    erzeugst Du Dir einen View, auf den Du in Zukunft wie auf eine Tabelle
    zurückgreifen kannst.

    Mit

    SELECT  
        per1.id,  
        per1.bezeichnung,  
        per1.textfarbe,  
        per1.wichtig,  
        per1.adr_unt,  
        per1.ort,  
        per1.vname,  
        per1.nname,  
        gv.anzahl  
    FROM tabelle1 AS per1  
    ...  
    INNER JOIN vw_gruppen_verteilung gv  
    ...  
    
    

    erledigst Du das Problem sauber, ohne MySQL-Spezifika irrigerweise zu
    mißbrauchen und ohne gewagte Konstruktionen.

    Die Alternative wäre ein Subselect. Wie dies genau aussehen könnte,
    kann ich nicht sagen, da Du die genauen Tabellenstrukturen geheimhältst.

    Dein jetztiger Lösungsversuch kann mich jedenfalls nicht überzeugen.

    Freundliche Grüße

    Vinzenz