AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Doppelte Tabelle in GROUP BY
Thema durchsuchen
Ansicht
Themen-Optionen

Doppelte Tabelle in GROUP BY

Ein Thema von ChEeTaH · begonnen am 3. Jul 2012 · letzter Beitrag vom 4. Jul 2012
Antwort Antwort
ChEeTaH

Registriert seit: 12. Jan 2009
49 Beiträge
 
Delphi XE2 Architect
 
#1

Doppelte Tabelle in GROUP BY

  Alt 3. Jul 2012, 21:36
Datenbank: MySql • Version: - • Zugriff über: -
Hallo,

ich habe einen Query über 4 Tabellen, wobei ich aus 2 Tabellen mit COUNT eine Gesamtanzahl berechne und aus einer den AVG aus verschiedenen Werten.
Dabei sind die COUNT's aus jeweils 2 Tabellen, wobei sie eine Verbindungstabelle _zusammen_ besitzen, d.h. sie haben diese Tabelle gemeinsam, bilden ihre Querys aber unabhängig voneinander.

wie kann ich das nun in die GROUP BY Klausel packen, wenn ich diese 3 Tabellen habe, 2 davon aber gleich sind? Als Ergebnis dieses Querys bekomme ich eine viel zu hohe COUNT zahl raus, ich vermute, ein Group by wird nicht richtig angewendet. Bisher hab ich nur die 2 unterschiedlichen Tabellen in der Klausel.

artikel_benutzer_wertung.vote müsste 2mal vorkommen

Code:
SELECT
    artikel.id AS ARTIKELID,
    artikel.name AS ARTIKELNAME,
    artikel_kategorien.name AS artikel_kategorien_name,
    artikel_benutzer.artikel_id AS artikel_benutzer_artikel_id,
    COUNT(artikel_benutzer.benutzer_id) AS `BENUTZERCOUNT`,
    artikel_benutzer_wertung.artikel_id AS artikel_benutzer_wertung_artikel_id,
    COUNT(artikel_benutzer_wertung.vote) AS `VOTECOUNT`,
    artikel_benutzer_wertung.product_id,
    AVG(artikel_benutzer_wertung.vote) AS `AVGVOTE`
FROM
    artikel,
    artikel_kategorien,
    artikel_benutzer,
    artikel_benutzer_wertung
WHERE
    artikel_benutzer.type != 0 AND artikel.artikel_kategorie_id = 15 AND
    artikel_benutzer.artikel_id = artikel.id AND artikel_benutzer_wertung.artikel_id = artikel.id AND artikel.artikel_kategorie_id = artikel_kategorie.id
GROUP BY artikel_benutzer.artikel_id , artikel_benutzer_wertung.artikel_id

Geändert von ChEeTaH ( 3. Jul 2012 um 21:41 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#2

AW: Doppelte Tabelle in GROUP BY

  Alt 3. Jul 2012, 22:53
Ich würde es so machen:
Code:
Group by
   artikel.id ,
   artikel.name ,
   artikel_kategorien.name AS artikel_kategorien_name,
   artikel_benutzer.artikel_id AS artikel_benutzer_artikel_id,
   artikel_benutzer_wertung.artikel_id AS artikel_benutzer_wertung_artikel_id,
   artikel_benutzer_wertung.product_id
Alles was nicht gezählt wird ins Group by.
Nach Deinen Ausführungen sind zwei Tabellen gleich. Wenn sie also den gleichen Inhalt haben, dann ist eine überflüssig.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector

Geändert von p80286 ( 3. Jul 2012 um 22:54 Uhr) Grund: Tippfehler
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#3

AW: Doppelte Tabelle in GROUP BY

  Alt 3. Jul 2012, 23:04
Zunächst einmal solltest du die neue Join-Syntax benützen.
Hier ein Beispiel mit nur 2 Tabellen:
SQL-Code:
SELECT [feldliste]
FROM artikel INNER JOIN artikel_kategorien ON artikel.artikel_kategorie_id = artikel_kategorie.id
WHERE artikel.preis > 100.0
Dadurch dass die Verknüpfung zweier Tabellen durch die ON-Klausel ausgedrückt wird, ist diese Syntax insgesamt leichter zu verstehen.
Bei der alten Syntax (alles in der WHERE-Klausel) kann man leicht eine Verknüpfung vergessen, was dann wie ein unterbestimmtes Gleichungssystem zu viele Datensätze liefert.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#4

AW: Doppelte Tabelle in GROUP BY

  Alt 4. Jul 2012, 09:34
Ich sehe hier keine gleichen Tabellen. Gäbe es welche, würde man sie in der From Clause eintragen und unterschiedliche Aliase vergeben.
Verschieden sind tatsächlich die verwendeten Namen der Tabelle(n) artikel_kategorie[n]. Vielleicht ein Copy / Paste Fehler , vielleicht aber auch original Abfragetext, dann würde es tatsächlich 2 fast glelichnamige Tabellen geben?!

Die verschiedenen Counts in einer Menge würde ich mal vergessen.

Ein Group By sollte auch und gerade bei MySQL(vermute ich, da es so in anderen Systemen gar nicht laufen würde) immer alle nicht aggregierten Felder einschließen, sonst kannst Du die Ergebnisse auch gleich auf der Kirmes bei der Wahrsagerin abholen.

Lieber so:
Code:
SELECT a.id AS A_ARTIKELID,
       a.name AS A_ARTIKELNAME,
       ak.name AS ak_kategorien_name,
       ab.artikel_id AS ab_artikel_id,
       ab.BENUTZERCOUNT,
       abw.artikel_id AS abw_artikel_id,
       abw.product_id AS abw_product_id,
       abw.AVGVOTE,
       abw.VOTECOUNT
  FROM artikel a, artikel_kategorien ak,
     ( select artikel_id, COUNT(ab.benutzer_id) AS BENUTZERCOUNT
         from artikel_benutzer
        group by artikel_id ) ab,
     ( select artikel_id, product_id,
                AVG(abw.vote) AS AVGVOTE, COUNT(abw.vote) AS VOTECOUNT
           from artikel_benutzer_wertung
          group by artikel_id, product_id ) abw
 WHERE ab.type != 0
   AND a.artikel_kategorie_id = 15
   AND a.artikel_kategorie_id = ak.id
   AND a.id = ab.artikel_id
   AND a.id = abw.artikel_id
Das könnte so funktionieren, wenn die Artikel eindeutig sind. Bei den Produkt_ID kann ich schwer voraussagen, wie die das Ergebnis beeinflussen.

Ansonsten muss alles noch mal gruppiert und die Aggregat Felder aus den Unterabfragen summiert werden.
Gruß, Jo
  Mit Zitat antworten Zitat
tgvoelker

Registriert seit: 9. Sep 2002
Ort: Oelsnitz, Vogtland
44 Beiträge
 
Delphi 12 Athens
 
#5

AW: Doppelte Tabelle in GROUP BY

  Alt 4. Jul 2012, 22:58
Ich nehme an, daß Du folgendes tun willst: Je Artikel ausgeben, wieviele Bewertungen abgegeben wurden, wie die durchschnittliche Bewertung ist und wievielen Benutzern der zugewiesen ist.

Zum Verständnis folgendes: in Deiner From-Klausel
Code:
FROM
    artikel,
    artikel_kategorien,
    artikel_benutzer,
    artikel_benutzer_wertung
bildest Du das Kreuzprodukt aller Datenmengen, aus dem Du dann mit Deiner Where-Klausel die Tupelkombinationen rausfischst, die den angegebenen Kriterien entsprechen.

Verwendest Du Joins, dann baut die Engine entsprechend der Bildungsvorschrift Kombinationen der Tupel.

Das Problem dabei ist nun, daß im Kreuzprodukt nicht-zuordbare Tupel garnicht ausgegeben werden, heißt, wenn ein Datensatz [artikel] existiert, für den kein Datensatz [artikel_benutzer_wertung] existiert, aber ein Datensatz [artikel_benutzer], dann siehst Du den NICHT in Deinem Ergebnis. Das ist bei dem Inner Join übrigens genauso.

Damit Du alle Artikel bekommst, mußt Du Outer Joins verwenden, die geben zusätzlich zu den gemäß Bildungsvorschrift gebildeten Tupelkombinationen auch die Nicht zuordenbaren aus: LEFT JOIN die nicht zuordenbaren, die links vom Operator stehen, RIGHT JOIN die rechts und FULL OUTER JOIN sowohl die rechts , als auch die links.

Zurück zu Deinem Beispiel: die Syntax ist abhängig davon, wie die Tabellen aufgebaut sind:
  1. Ist product_id eindeutig je Artikel?
  2. wird in artikel_benutzer_wertung benutzerspezifisch die Artikelbewertung erfaßt, d.h. ist dadrin eine Referenz auf den Benutzer enthalten?
  3. in diesem Kontext: sind die Bewertungen symmetrisch, d.h. jede Einzelbewertung hat die gleiche Wichtung? (Hintergrund: wenn ein Benutzer 2 mal bewertet, ein anderer nur einmal, dann beeinflußt die Doppelbewertung des einen Benutzers das ergebnis mehr, als die Einfachbewertung des anderen)
Thomas Völker
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz