Reputation: 65
I have the following SQL:
SELECT t.teilnehmer_id, t.familienname, t.vorname, t.ort, t.ortsteil, t.kontrolle_ertrag, t.kontrolle_1j, t.kontrolle_brache,
SUM(fe.nutzflaeche) AS nutzflaeche_ertrag, GROUP_CONCAT(fe.nutzflaeche) AS einzelfl_ertrag,
SUM(fp.nutzflaeche) AS nutzflaeche_pflanzj, GROUP_CONCAT(fp.nutzflaeche) AS einzelfl_pflanzj,
SUM(fb.nutzflaeche) AS nutzflaeche_brache, GROUP_CONCAT(fb.nutzflaeche) AS einzelfl_brache,
SUM(fn.nutzflaeche) AS nutzflaeche_nicht_aush, GROUP_CONCAT(fn.nutzflaeche) AS einzelfl_nicht_aush
FROM teilnehmer t
LEFT JOIN anrede a ON (t.anrede_id = a.anrede_id)
LEFT JOIN antragsform af ON (t.antragsform_id = af.antragsform_id)
LEFT JOIN bank b ON (t.bank_id = b.bank_id)
LEFT JOIN flurverzeichnis fe ON (t.teilnehmer_id = fe.teilnehmer_id AND fe.kulturbez = 'E')
LEFT JOIN flurverzeichnis fp ON (t.teilnehmer_id = fp.teilnehmer_id AND fp.kulturbez = 'P')
LEFT JOIN flurverzeichnis fb ON (t.teilnehmer_id = fb.teilnehmer_id AND fb.kulturbez = 'B')
LEFT JOIN flurverzeichnis fn ON (t.teilnehmer_id = fn.teilnehmer_id AND fn.kulturbez = 'N')
WHERE 1 = 1
GROUP BY t.teilnehmer_id
ORDER BY familienname, vorname
The sum doesn't reflect the correct areas if there is a match in more than one kulturbez. E.g. if I have 5 rows with kulturbez 'E' and 2 rows with kulturbez 'N', each 'E' row shows up twice and each 'N' row shows up 5 times. Any suggestions on how to redo the SQL to only sum each row with the matching kulturbez once? Thanks,
Gunter
Upvotes: 0
Views: 34
Reputation: 15941
As indicated in my comment, unavoidable 1:N joins usually need subqueries to calculate aggregate values appropriately; but it looks like your need can be solved with conditional aggregation, like so:
SELECT t.teilnehmer_id, t.familienname, t.vorname, t.ort, t.ortsteil, t.kontrolle_ertrag, t.kontrolle_1j, t.kontrolle_brache
, SUM(CASE WHEN f.kulturbez = 'E' THEN f.nutzflaeche ELSE NULL END) AS nutzflaeche_ertrag
, GROUP_CONCAT(CASE WHEN f.kulturbez = 'E' THEN f.nutzflaeche ELSE NULL END) AS einzelfl_ertrag
, SUM(CASE WHEN f.kulturbez = 'P' THEN f.nutzflaeche ELSE NULL END) AS nutzflaeche_pflanzj
, GROUP_CONCAT(CASE WHEN f.kulturbez = 'P' THEN f.nutzflaeche ELSE NULL END) AS einzelfl_pflanzj
, SUM(CASE WHEN f.kulturbez = 'B' THEN f.nutzflaeche ELSE NULL END) AS nutzflaeche_brache
, GROUP_CONCAT(CASE WHEN f.kulturbez = 'B' THEN f.nutzflaeche ELSE NULL END) AS einzelfl_brache
, SUM(CASE WHEN f.kulturbez = 'N' THEN f.nutzflaeche ELSE NULL END) AS nutzflaeche_nicht_aush
, GROUP_CONCAT(CASE WHEN f.kulturbez = 'N' THEN f.nutzflaeche ELSE NULL END) AS einzelfl_nicht_aush
FROM teilnehmer t
LEFT JOIN anrede a ON (t.anrede_id = a.anrede_id)
LEFT JOIN antragsform af ON (t.antragsform_id = af.antragsform_id)
LEFT JOIN bank b ON (t.bank_id = b.bank_id)
LEFT JOIN flurverzeichnis f ON (t.teilnehmer_id = fe.teilnehmer_id)
WHERE 1 = 1
GROUP BY t.teilnehmer_id
ORDER BY familienname, vorname
Aggregate functions ignore NULL values for the most part. (Also, technically ELSE NULL
is optional, as it is the assumed value if ELSE
is not specified; but is good practice to make your intent clear.)
Upvotes: 1