Sebastian Fischer: Aggregatsfunktionen, group by, unvorhersagbare Ergebnisse

Beitrag lesen

Nein, mit dem GROUP BY.

  • Sven Rautenberg

Hallo Sven,

zum einen habe ich den Join überarbeitet, damit wenigstens da kein(weniger?) Fehler mehr auftreten, zum anderen habe ich keine Probleme mit dem Ergebniss von MIN(). Das heißt die Ergebnisse des GROUP BY sind wie vorher gesehen richtig. Das Problem entsteht bei dem Wert der nicht gegroupt wird.

Zu den Spalten kann ich nur sagen, dass bis auf den Preis und das Datum des Preises alle Werte einer ProduktID gleich sind. Das heisst bei Übergabe einer ProduktID variieren einzig und alleine die Preise und deren jeweiliges Erstellungsdatum.

Problem ist, dass ich nicht das letzte Datum erhalte sondern ein beliebiges. Es ist also immer noch die Frage offen, warum ich trotz ORDER BY nicht an das richtige Ergebniss gelange.

Ich bin jetzt mal testweise hergegangen und habe alle abgefragten Spalten im GROUP BY eingefügt. So lange ich alle Spalten einfüge und die currentprice Spalte weglasse, erhalte ich als Ergbeniss korrekte Werte für die Aggregatsfunktionen und für eindeutigen Werte des Preises. Nur wird dann immer noch nicht der richtige currentprice ausgegeben.
Schliesse ich den currentprice zusätzlich noch mit ein erhalte ich mehrere Zeilen und die Aggregatsfunktionen liefern mir Mist zurück.

Zur Verdeutlichung hier mal das State und die beiden Ergebnisse:

SELECT
   tx_sfpricetracker_lists.owner,
   tx_sfpricetracker_products.producer,
   tx_sfpricetracker_products.name,
   tx_sfpricetracker_products.description,
   tx_sfpricetracker_products.link,
   tx_sfpricetracker_products.amount,
   MIN(tx_sfpricetracker_prices.price) AS lowestprice,
   MAX(tx_sfpricetracker_prices.price) AS highestprice,
   tx_sfpricetracker_prices.price AS currentprice

FROM
   tx_sfpricetracker_products
   INNER JOIN (tx_sfpricetracker_products_prices_mm
   INNER JOIN tx_sfpricetracker_prices ON tx_sfpricetracker_products_prices_mm.uid_foreign = tx_sfpricetracker_prices.uid
   ) ON tx_sfpricetracker_products.uid = tx_sfpricetracker_products_prices_mm.uid_local

INNER JOIN (tx_sfpricetracker_lists_products_mm
   INNER JOIN tx_sfpricetracker_lists ON tx_sfpricetracker_lists_products_mm.uid_local = tx_sfpricetracker_lists.uid
   ) ON tx_sfpricetracker_products.uid = tx_sfpricetracker_lists_products_mm.uid_foreign

WHERE
   tx_sfpricetracker_products.uid = 2
   AND tx_sfpricetracker_lists.owner = 1

GROUP BY
   tx_sfpricetracker_lists.owner,
   tx_sfpricetracker_products.producer,
   tx_sfpricetracker_products.name,
   tx_sfpricetracker_products.description,
   tx_sfpricetracker_products.link,
   tx_sfpricetracker_products.amount,
   currentprice <------- durch weglassen ändert sich das Ergebniss
ORDER BY tx_sfpricetracker_prices.crdate desc

Ergebniss mit currentprice in GROUP BY:
"owner","producer","name","description","link","amount","lowestprice","highestprice","currentprice"
"1","Samsung","250GB Samsung SP2504C SATAII","Festplatte Sata","http://www.mindfactory.de/cgi-bin/MindStore.storefront/DE/Product/0017325",1,"62.70","62.70","62.70"
"1","Samsung","250GB Samsung SP2504C SATAII","Festplatte Sata","http://www.mindfactory.de/cgi-bin/MindStore.storefront/DE/Product/0017325",1,"62.69","62.69","62.69"
"1","Samsung","250GB Samsung SP2504C SATAII","Festplatte Sata","http://www.mindfactory.de/cgi-bin/MindStore.storefront/DE/Product/0017325",1,"58.54","58.54","58.54"

Wunderbar sortierter Preis mit aktuellem Preis oben aber total vergurkte Aggregatfunktionen.

Ohne currentprice in GROUP BY:
"owner","producer","name","description","link","amount","lowestprice","highestprice","currentprice"
"1","Samsung","250GB Samsung SP2504C SATAII","Festplatte Sata","http://www.mindfactory.de/cgi-bin/MindStore.storefront/DE/Product/0017325",1,"58.54","62.70","62.69"

Jetzt sind die Werte der Aggregatsfunktion korrekt aber der currentprice ist dafür nicht der aktuelle sondern ein unvorhersehbarer.

Beim rumexperimentieren mit dem State ist mir dann auch noch aufgefallen, dass wenn ich das GROUP BY und die Aggregatsfunktionen entferne, es zu ein Fehler kommt. Denn obwohl alle Felder eindeutig über den Tabellennamen und den Feldnamen angesprochen werden, erhalte ich die Meldung "Column 'uid' in field list is ambiguous". Das kann aber nicht sein, denn kein Feld wird hier zweideutig verwendet. Zum testen habe ich folgenden auf ein minimum abgespreckten State verwendet:

SELECT
   tx_sfpricetracker_lists.owner,
   tx_sfpricetracker_prices.price

FROM
   tx_sfpricetracker_products
   INNER JOIN (tx_sfpricetracker_products_prices_mm
   INNER JOIN tx_sfpricetracker_prices ON tx_sfpricetracker_products_prices_mm.uid_foreign = tx_sfpricetracker_prices.uid
   ) ON tx_sfpricetracker_products.uid = tx_sfpricetracker_products_prices_mm.uid_local

INNER JOIN (tx_sfpricetracker_lists_products_mm
   INNER JOIN tx_sfpricetracker_lists ON tx_sfpricetracker_lists_products_mm.uid_local = tx_sfpricetracker_lists.uid
   ) ON tx_sfpricetracker_products.uid = tx_sfpricetracker_lists_products_mm.uid_foreign

WHERE
   tx_sfpricetracker_products.uid = 2

Wenn es nicht am JOIN liegt, dann weiss ich nicht was da falsch sein soll. Davon ab soll der letzte State nicht das Endergebniss sein. Den habe ich nur verwendet um ein Abfrage zu haben die auf ein Minimum an Fehlerquellen reduziert ist. Leider habe ich mich da wohl getäuscht.

So langsam bin ich mit meinem SQL-Latein am Ende.

Gruß
Sebastian