Group by MySql,PostGres

Hallo liebe PG-Gemeinde,

ich habe ein Projekt das auf Mysql(5.0) läuft.
Jetzt checke ich gerade wie groß der Aufwand ist, auch PG(8.3) zu unterstützen. Das meisste geht ja auch problemlos!

In einigen Statements hab offensichtlich ein Problem mit dem ‘group by’

Beispiel:

sortstamm: Sortiment (Container) von Artikeln (so_id)
sorttermin: Planungstermine zum Sortiment (sot_soid)
sortdetail: Verweise auf (n) Artikel und deren Mengen (sod_sotid)
artikel: hat den artikel und zeigt auf die artpreis
artpreis: zeitbhängige Preise

Folgendes Statement bringt unter MySql das gewünschte Ergebnis.

[html]


SELECT
so.SO_NAME,sot.sot_soid, sot.sot_id, sot.sot_beginn,
CASE
WHEN (a.a_einheit= 3 AND a.a_refgewicht> 0) THEN
round(ap.ap_preis * a.a_refgewicht * sod.sod_menge,2)
ELSE
round(sum(ap.ap_preis * sod.sod_menge), 2)
END AS sod_gpreis
FROM sortstamm so
LEFT JOIN sorttermin sot ON sot.sot_aktiv = 1 AND sot.sot_soid = so.so_id
AND sot.sot_beginn=
( --> Den letzen Planungstermin holen…
SELECT max(sot2.sot_beginn) AS max FROM sorttermin sot2
WHERE sot2.sot_soid = so.so_id
)
LEFT JOIN sortdetail sod ON sod.sod_sotid = sot.sot_id
LEFT JOIN artikel a ON a.a_id = sod.sod_artid
LEFT JOIN artikelpreis ap ON a.a_id = ap.ap_aid
AND ap.ap_datum =
( --> Das letztgültige Preisdatum holen…
SELECT max(ap2.ap_datum) AS max FROM artikelpreis ap2
WHERE ap.ap_aid = ap2.ap_aid AND ap2.ap_datum<=now()
)
WHERE so.so_aktiv = 1
GROUP BY sot.sot_soid
ORDER BY so.SO_NAME
[/html]



Ich bastele mit ‘pgAdmin III’ und stelle fest das die ‘GROUB BY’-Klausel wie folgt aussehen müsste:


GROUP BY sot.sot_soid,
sot.sot_id, sot.sot_beginn,
a.a_einheit,a.a_refgewicht,ap.ap_preis,sod.sod_menge, – wird NICHT selektiert!
so.SO_NAME --??? nur in ORDER BY!

Wenn so gruppiere bekomme ich natürlich ein falsches(nicht gewolltes) Ergebnis.

Meine Frage(n):
1.)
Ich habe so einige Statements in dem ich unter MySql nicht nach allen selektierten Spalten gruppiere!
Wie macht Ihr das ? :confused:

2.)
Das o.g. Statement läuft unter MySql als View.
Ich brauche eine Lösung die kein ‘SELECT’ in der ‘FROM’-KLausel beeinhaltet’.

Ein Dump kann ich Euch schicken wenn ihr wollt…


Vielen Dank für Eure Mühe…

Auch so. Gruppiert wird nur, wenn es nötig ist. Nötig wird es bei Aggregationen, wovon ich keine bei Dir sehe.

2.)
Das o.g. Statement läuft unter MySql als View.
Ich brauche eine Lösung die kein ‘SELECT’ in der ‘FROM’-KLausel beeinhaltet’.

Keine Ahnung, was MySQL macht. In PG kannst Du jedes SELECT, egal ob mit oder ohne SELECT im FROM, auch als VIEW schreiben.

Ein Dump kann ich Euch schicken wenn ihr wollt…

Ein simples Testbeispiel mit ein oder 2 beteiligten Tabellen, auf die nötigsten Spalten reduziert, als Bleistift tät reichen.

Andreas

Ja, im Statement oben ist ein Copy&Paste Fehler drin.
(round(sum(ap.ap_preis * sod.sod_menge), 2).
Schon klar, erst lesen dann posten. Hat aber keine Auswirkung auf das Problem.

1.)
das mt dem View in MySql vergiss erstmal dafür finde ich ne Lösung.
Das hier ist wichtiger!

2.)
Im Anhang ist ein Dump mit den Beispieltabellen. Der Vollständigkeit halber sind da alle Tabellen drin.

3.)
Ich habe das Problem auf das ‘CASE’ eingekreist.
Ich habe da keine Aggregationen drin und müsste auch so funktionieren,

[html]


SELECT
sod_sotid,
CASE
WHEN (a.a_einheit= 3 AND a.a_refgewicht> 0) THEN
a.a_refgewicht * sod.sod_menge
ELSE
sod.sod_menge
END AS sod_gpreis
FROM sortdetail sod
LEFT JOIN artikel a ON a.a_id = sod.sod_artid
WHERE sod.sod_sotid =2
GROUP BY sod_sotid
ORDER BY sod.sod_soid
[/html]

Aber da bekomme ich folgenden Error:

column “a.a_einheit” must appear in the GROUP BY clause or be used in an aggregate function…

Damit dieses Statement ausgeführt wird muss ich ALLE Spalten in die
Group by Klausel aufnehmen sogar sod.sod_soid die nur in der ORDER BY steht :confused:

[html]

GROUP BY sod_sotid,a.a_einheit,a.a_refgewicht,sod.sod_menge,sod.sod_soid

[/html]
Achtung: Nicht verwechseln sod_soid & sod_sotid

Das Ergebnis ist nicht das was ich will ich will (in dem kleinen Beispiel) nur nach sod_soid gruppieren!

Irgendeine Idee?

Das tue ich mir nun nicht extra an…

3.)
Ich habe das Problem auf das ‘CASE’ eingekreist.
Ich habe da > keine Aggregationen > drin und müsste auch so funktionieren,

Eben. Es müßte funktionieren, und zwar gänzlich ohne GROUP BY.



column “a.a_einheit” must appear in the GROUP BY clause or be used in an aggregate function…

Ist doch eindeutig, oder? Wenn Du nach etwas gruppieren willst, so müssen alle Spalten ENTWEDER als gruppierungsmerkmal dienen ODER in einer Aggregatfunktion sein.


Damit dieses Statement ausgeführt wird muss ich ALLE Spalten in die
Group by Klausel aufnehmen …

Genau. Oder keine. Wenn Du nach allen gruppierst, hast Du faktisch ein DISTINCT. Vielleicht willst Du ja auch nur das.

Das Ergebnis ist nicht das was ich will ich will (in dem kleinen Beispiel) nur nach > sod_soid > gruppieren!

Wenn Du ein GROUP BY machst, und zwar nur für einen Teil der Spalten, dann muß PG wissen, wie Du das gruppieren willst. Ohne Aggregatfunktion auf die anderen Spalten wäre PG gezwungen, Zeilen wegzuwerfen. Und wenn Du nicht sagst, welche zeilen wegzuwerfen sind, müßte PG dies für ich erreten. Tut es nicht, Feature. Um PG zu sagen, was es wegwerfen soll, hat es eine Erweiterung: DISTINCT ON (…), wie man das nutzt, steht in der Doku.

Falls das Verhalten von MySQL solch eine Abfrage wie Deine zuläßt, dann ist das was anderes. Und zwar ein Bug.

Andreas

Jepp, habs jetzt gefressen. :slight_smile:

Vielen Dank für Deine Zielführung…