Entwickler-Ecke

Datenbanken - Problem mit DB-Abfrage und Group By


DelphiGreenhorn - Di 11.12.07 10:24
Titel: Problem mit DB-Abfrage und Group By
Hallo Forum,

habe hier ein Statement bei dem Altersgruppen ermittelt werden sollen.
Pro Fall können mehrere Personen beteiligt sein.
Es soll pro Fall ausgegeben werden, welche Altergruppen vertreten sind.

Beispiel

Quelltext
1:
2:
3:
4:
FallID - Altergruppe 1 - Altergruppe 2 - Altergruppe 3 - Altergruppe 4
1001   - 1             - 1             - 0             - 0
1002   - 0             - 1             - 1             - 1
1003   - 0             - 0             - 0             - 1

Das Statement sie wie folgt aus:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
select fallID
(case 
 when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (0,1,2) then 1 else ''
      end)as Altersgruppe1,
(case 
 when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (3,4,5) then 1 else ''
      end) as Altersgruppe2,
(case 
when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (6,7,8,9,10,11) then 1 else ''
          end) as Altersgruppe3,
(case 
   when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (12,13) then 1 else ''
          end) as Altersgruppe14
from fall, personendaten, fallbeteiligte 
where fall.fallid = fallbeteiligte.fall_fk and fallbeteiligte.personen_fk = personendaten.personid
group by fallID, geburtsdatum


Eigentlich hätte ich hier gerne nur nach fallID groupiert, muss aber das geburtsdatum auch mit aufnehmen.

Irgendwie müssen die Caseanweisungen aus dem select oben raus und ins from, oder?
Meine Ausgabe im Moment sieht wie folgt aus:

Quelltext
1:
2:
3:
4:
5:
6:
7:
FallID - Altergruppe 1 - Altergruppe 2 - Altergruppe 3 - Altergruppe 4
1001   - 1             - 0             - 0             - 0
1001   - 0             - 1             - 0             - 0
1002   - 0             - 1             - 0             - 0
1002   - 0             - 0             - 1             - 0
1002   - 0             - 0             - 0             - 1
1003   - 0             - 0             - 0             - 1


Ich hätte halt gerne pro fallID auch nur eine Zeile.

Hoffe irgendjemand versteht mein Problem?


mkinzler - Di 11.12.07 10:41

Wenn es pro Fall mehrere Personen(Geburtstage) gibt, wie willst du diese dann zusammenfassen (kleines, größtest)?


DelphiGreenhorn - Di 11.12.07 11:18

Ich würde gerne wissen, ob es überhaupt Personen gibt, deren Geburtsdatum in den Bereich der vier Altergruppen fällt und wenn es diese gibt, soll entsprechend nur die Altergruppe pro Fall mit einer 1 markiert werden.
Bei dem von mir verwendeten Statement werde ich ja dazu gezwungen nach geburtsdatum mitzugruppieren, obwohl ich eigentlich ja nur nach fallid gruppieren wollen würde.
Hoffe ich konnte deine Frage damit beantworten, sonst hab ich sie glaub ich nicht richtig verstanden :)

MfG


mkinzler - Di 11.12.07 11:30

Welches DBMS? Ich würde das dann in 2 Schritten machen.


DelphiGreenhorn - Di 11.12.07 11:33

Im moment läuft es erst auf SQL Server 2005, später muss es dann auch Oracle 10 und Informix 9 laufen.
Das Statement ist für eine MIS-Auswertung. Ich habe auch nur die Möglichkeit es in einem Schritt auszuführen.
Ich könnte höchstens eine Function einsetzen...

MfG


mkinzler - Di 11.12.07 11:49


SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
select * from 

    select fallID
    (
        case 
             when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (0,1,2then 1 else ''
        end)as Altersgruppe1,
    (case 
 when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (3,4,5then 1 else ''
      endas Altersgruppe2,
(case 
when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (6,7,8,9,10,11then 1 else ''
          endas Altersgruppe3,
(case 
   when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (12,13then 1 else ''
          endas Altersgruppe14
from fall, personendaten, fallbeteiligte 
where fall.fallid = fallbeteiligte.fall_fk and fallbeteiligte.personen_fk = personendaten.personid)

group by fallID, geburtsdatum;


Agawain - Di 11.12.07 11:52

wieso mußt Du nach Geburtsdatum gruppieren?
Eigentlich reicht es, wenn es im Select mit drin ist.


mkinzler - Di 11.12.07 11:54

user profile iconAgawain hat folgendes geschrieben:
wieso mußt Du nach Geburtsdatum gruppieren?
Eigentlich reicht es, wenn es im Select mit drin ist.

Wenn er das nicht macht verliert er die einzelnen Geburtsdaten.


Agawain - Di 11.12.07 11:59

wenn sie im Select stehen nicht.
Bei der Abfrage wird doch jeder einzelne Datensatz untersucht.

Stell gerade fest, muss noch nicht mal im Select drin sein


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
SELECT  GAMNr, Lieferant, ArtikelNr, Erfassungsjahr, 
SUM(CASE Erfassungsmonat WHEN 3 THEN AnzahlIst ELSE 0 ENDAS '1. Q.',
SUM(CASE Erfassungsmonat WHEN 6 THEN AnzahlIst ELSE 0 ENDAS '2. Q.',
SUM(CASE Erfassungsmonat WHEN 9 THEN AnzahlIst ELSE 0 ENDAS '3. Q.',
SUM(CASE Erfassungsmonat WHEN 12 THEN AnzahlIst ELSE 0 ENDAS '4. Q.',
SUM(AnzahlIst) AS 'Gesamt'
FROM tb_absatz GROUP BY GAMNr, ArtikelNr, Lieferant, ErfassungsJahr


In diesem Beispiel wird der Erfassungsmonat untersucht, ist aber in der Ausgabe nicht enthalten.

Funzt


DelphiGreenhorn - Di 11.12.07 12:01

user profile iconAgawain hat folgendes geschrieben:
wenn sie im Select stehen nicht.
Bei der Abfrage wird doch jeder einzelne Datensatz untersucht.

Stell gerade fest, muss noch nicht mal im Select drin sein


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
SELECT  GAMNr, Lieferant, ArtikelNr, Erfassungsjahr, 
SUM(CASE Erfassungsmonat WHEN 3 THEN AnzahlIst ELSE 0 ENDAS '1. Q.',
SUM(CASE Erfassungsmonat WHEN 6 THEN AnzahlIst ELSE 0 ENDAS '2. Q.',
SUM(CASE Erfassungsmonat WHEN 9 THEN AnzahlIst ELSE 0 ENDAS '3. Q.',
SUM(CASE Erfassungsmonat WHEN 12 THEN AnzahlIst ELSE 0 ENDAS '4. Q.',
SUM(AnzahlIst) AS 'Gesamt'
FROM tb_absatz GROUP BY GAMNr, ArtikelNr, Lieferant, ErfassungsJahr


In diesem Beispiel wird der Erfassungsmonat untersucht, ist aber in der Ausgabe nicht enthalten.

Funzt


Das ist auch richtig, weil der Erfassungsmonat sich in einer Aggregatsfunktion (in dem Fall sum()) befindet.
Dann wird dieser im Group by von der DB auch nicht verlangt


Siluro - Di 11.12.07 12:10

Hi,
probiers mal so:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
select fallID, ag1.ag as Altersgruppe1, ag2.ag as Altersgruppe2, ag4.ag as Altersgruppe4, ag4.ag as Altersgruppe4
from fall a
left join fallbeteiligte b on a.fallid = b.fall_fk
left join (select personid, case when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (0,1,2) then 1 end as ag from persondaten) ag1 on b.personen_fk = ag1.personid and ag1.ag = 1
left join (select personid, case when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (3,4,5) then 1 end as ag from persondaten) ag2 on b.personen_fk = ag2.personid and ag2.ag = 1
left join (select personid, case when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (6,7,8,9,10,11) then 1 end as ag from persondaten) ag3 on b.personen_fk = ag3.personid and ag3.ag = 1
left join (select personid, case when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (12,13) then 1 end as ag from persondaten) ag4 on b.personen_fk = ag4.personid and ag4.ag = 1
where ag1.ag > 0 or ag2.ag > 0 or ag3.ag > 0 or ag4.ag > 0


Hoffe das hilft dir weiter, sollte eigentlich funktionieren.

MfG

Björn


DelphiGreenhorn - Di 11.12.07 12:51

user profile iconSiluro hat folgendes geschrieben:
Hi,
probiers mal so:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
select fallID, ag1.ag as Altersgruppe1, ag2.ag as Altersgruppe2, ag4.ag as Altersgruppe4, ag4.ag as Altersgruppe4
from fall a
left join fallbeteiligte b on a.fallid = b.fall_fk
left join (select personid, case when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (0,1,2) then 1 end as ag from persondaten) ag1 on b.personen_fk = ag1.personid and ag1.ag = 1
left join (select personid, case when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (3,4,5) then 1 end as ag from persondaten) ag2 on b.personen_fk = ag2.personid and ag2.ag = 1
left join (select personid, case when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (6,7,8,9,10,11) then 1 end as ag from persondaten) ag3 on b.personen_fk = ag3.personid and ag3.ag = 1
left join (select personid, case when floor(datediff(dd,geburtsdatum,'31.12.2007')/365.25) IN (12,13) then 1 end as ag from persondaten) ag4 on b.personen_fk = ag4.personid and ag4.ag = 1
where ag1.ag > 0 or ag2.ag > 0 or ag3.ag > 0 or ag4.ag > 0


Hoffe das hilft dir weiter, sollte eigentlich funktionieren.

MfG

Björn


Danke :)
Funktioniert! Vielen Dank auch an alle anderen die geholfen haben.

MfG