Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   InterBase Group By / Left Join / 3xgleiche Tabelle?? (https://www.delphipraxis.net/179949-interbase-group-left-join-3xgleiche-tabelle.html)

Agasch 13. Apr 2014 06:54

Datenbank: InterBase • Version: XE • Zugriff über: Delphi Prof. XE

InterBase Group By / Left Join / 3xgleiche Tabelle??
 
Moin,
versuche gerade das Gruppieren/Berechnen von Daten und das Anwenden von Joins zu erlernen. Hier stehe ich aber irgendwie auf dem Schlauch....

Habe 2 Tabellen:

Tabelle: Personal
Feld: PERSONAL_ID

Daten in der Tabelle: PERSONAL_ID=1


Tabelle: FEHLTAGE
Felder: FEHLTAGE_ID, FEHLTAGE_PERSONALID, FEHLTAGE_ARBEITSTAGE, FEHLTAGE_ART
-> ART bedeutet: U(rlaub), K(rank), F(ehlt)

Daten in der Tabelle "FEHLTAGE":

FEHLTAGE_ID FEHLTAGE_PERSONALID FEHLTAGE_ART FEHLTAGE_ARBEITSTAGE
=========== =================== ============ ====================
1 1 U 10
2 1 U 7
3 1 F 1
4 1 K 5
5 1 K 2


d.h
PERSONAL_ID hat dann: 17 Tage Urlaub, 1 Tag gefehlt und 7 Tage krank gemacht.


Ich will jetzt auf die Tabelle Fehltage 3x zugreifen:

select
P.PERSONAL_ID,
Sum(U.FEHLTAGE_ARBEITSTAGE) as URLAUB,
Sum(F.FEHLTAGE_ARBEITSTAGE) as FEHLTAGE,
Sum(K.FEHLTAGE_ARBEITSTAGE) as KRANK

from PERSONAL P
LEFT JOIN FEHLTAGE U ON (U.FEHLTAGE_PERSONALID=P.PERSONAL_ID AND U.FEHLTAGE_ART='U')
LEFT JOIN FEHLTAGE F ON (F.FEHLTAGE_PERSONALID=P.PERSONAL_ID AND F.FEHLTAGE_ART='F')
LEFT JOIN FEHLTAGE K ON (K.FEHLTAGE_PERSONALID=P.PERSONAL_ID AND K.FEHLTAGE_ART='K')
GROUP BY P.PERSONAL_ID


Richtig wäre:
PERSONAL_ID=1 URLAUB=17 FEHLTAGE=1 KRANK=7

Bekomme jedoch:
PERSONAL_ID=1 URLAUB=31 FEHLTAGE=4 KRANK=14


Setze ich meine SQL_Anweisung schrittweise ein, dh nur ein Left Join, bekomme ich den richtigen Wert, aber 2 oder 3 liefern die falschen Werte.
Wie müüste das richtig aussehen?

Danke im Voraus
Andreas

geesmith 13. Apr 2014 08:48

AW: InterBase Group By / Left Join / 3xgleiche Tabelle??
 
Hi

Mit left join bist du ja grundsätzlich richtig unterwegs. Zeigt er dir die Werte ohne Group -By denn richtig an? Versuch mal den Group By in einem übergeordneten SELECT zu machen. Wäre möglich dass ein Group By direkt mit left join Probleme verursacht... also:

SELECT P.PERSONAL_ID, SUM(URLAUB),SUM(FEHLTAGE),SUM(KRANK)
FROM(
SELECT
P.PERSONAL_ID,
U.FEHLTAGE_ARBEITSTAGE as URLAUB,
F.FEHLTAGE_ARBEITSTAGE as FEHLTAGE,
K.FEHLTAGE_ARBEITSTAGE as KRANK

from PERSONAL P
LEFT JOIN FEHLTAGE U ON (U.FEHLTAGE_PERSONALID=P.PERSONAL_ID AND U.FEHLTAGE_ART='U')
LEFT JOIN FEHLTAGE F ON (F.FEHLTAGE_PERSONALID=P.PERSONAL_ID AND F.FEHLTAGE_ART='F')
LEFT JOIN FEHLTAGE K ON (K.FEHLTAGE_PERSONALID=P.PERSONAL_ID AND K.FEHLTAGE_ART='K')
)
GROUP BY P.PERSONAL_ID

Geht das?

Agasch 13. Apr 2014 09:02

AW: InterBase Group By / Left Join / 3xgleiche Tabelle??
 
Hi, IntreBase unterstützt es leider nicht

Sir Rufo 13. Apr 2014 09:11

AW: InterBase Group By / Left Join / 3xgleiche Tabelle??
 
Mit dem Alias U werden 2 Sätze angesprochen, mit F 1 und mit K 2.
Das Ergebnis, worauf dann das GROUP BY angewendet wird besteht also aus 2x2x1 = 4 Sätzen.
Kann also schon vom Ansatz nicht stimmen (das ist auch die Erklärung, warum bei Fehltagen eine 4 herauskommt, weil die 4 mal berücksichtigt/aufsummiert werden).

jobo 13. Apr 2014 10:59

AW: InterBase Group By / Left Join / 3xgleiche Tabelle??
 
Für Übungszwecke ist der Join zur Personaltabelle vielleicht sinnvoll, technisch aber hier vollkommen unnötig.
Du benötigst nur die Fehltagetabelle für die Ausgabe, der Join zur Personaltabelle bringt keinen Mehrwert in Deinem Beispiel.

Das wäre erst gegeben, wenn Du
a) einen weiteren Wert aus Personal ausgeben willst, z.B. Name
b) eine Liste aller Personaldaten haben willst, auch wenn gar keine Fehltage vorhanden sind.

Dann würde ich jede "Einzelmenge" (die 3 Fehlarten) separat aufsummieren und dann joinen. So müsste in deinem Beispiel eine Zeile rauskommen.

Agasch 13. Apr 2014 11:03

AW: InterBase Group By / Left Join / 3xgleiche Tabelle??
 
Hi,
mein Bespiel zeigt nur das Wichtigste. Die Personaltabelle zeigt alle Informnationen und greift auf weitere Tabellen zu (Anschriften, Anreden usw). Das funktioniert auch alles, nur an der Stelle mit den Fehltagen gibs einen Fehler, daher reduzierte ich es auf minimum, bis ich den Fehler verstanden/behoben habe

mkinzler 13. Apr 2014 11:10

AW: InterBase Group By / Left Join / 3xgleiche Tabelle??
 
Oder

SQL-Code:
select
    P.PERSONAL_ID,
    Sum(U.FEHLTAGE_ARBEITSTAGE) as URLAUB,
    Sum(F.FEHLTAGE_ARBEITSTAGE) as FEHLTAGE,
    Sum(K.FEHLTAGE_ARBEITSTAGE) as KRANK
from
    PERSONAL P
        LEFT JOIN FEHLTAGE U ON U.FEHLTAGE_PERSONALID=P.PERSONAL_ID
        LEFT JOIN FEHLTAGE F ON F.FEHLTAGE_PERSONALID=P.PERSONAL_ID
        LEFT JOIN FEHLTAGE K ON K.FEHLTAGE_PERSONALID=P.PERSONAL_ID
where
    U.FEHLTAGE_ART='U'AND F.FEHLTAGE_ART='F' AND K.FEHLTAGE_ART='K'
GROUP BY
    P.PERSONAL_ID;

Agasch 13. Apr 2014 11:29

AW: InterBase Group By / Left Join / 3xgleiche Tabelle??
 
auch falsch^^

Richtig wäre:
PERSONAL_ID=1 URLAUB=17 FEHLTAGE=1 KRANK=7

Bekomme jedoch:
PERSONAL_ID=1 URLAUB=34 FEHLTAGE=4 KRANK=14

Sir Rufo 13. Apr 2014 11:32

AW: InterBase Group By / Left Join / 3xgleiche Tabelle??
 
Ja logisch. Es hat sich seit meiner Aussage ja auch nichts Wesentliches an der Abfrage verändert. Es bleibt bei 4 Zeilen über die der GROUP BY läuft.

Versuch doch mal die Tabelle mit den Fehltagen nur einmal zu joinen und für die Urlaubstage (als Beispiel) summierst dur nur, wenn die Art = U ist.

In SQL
SQL-Code:
SUM( IF( ... ) )
.

Der Rest erfolgt analog dazu ...

Agasch 13. Apr 2014 12:08

AW: InterBase Group By / Left Join / 3xgleiche Tabelle??
 
Das ist es... warum einfach wenns kompliziert geht^^

Also das funktioniert (IF gibs in Interbase nicht, aber case):
Der Server zeigt es richtig an. Werde schauen, wie weit ich es noch verfeinern kann (zB wenn FEHLTAGE_ARBEITSTAGE= NULL sind, event. 2 case):

select
Sum(case when FEHLTAGE_ART='U' then FEHLTAGE_ARBEITSTAGE else 0 end) as URLAUB_GENOMMEN,
Sum(case when FEHLTAGE_ART='K' then FEHLTAGE_ARBEITSTAGE else 0 end) as KRANK,
Sum(case when FEHLTAGE_ART='F' then FEHLTAGE_ARBEITSTAGE else 0 end) as FEHLTAGE,
PERSONAL_ID

from PERSONAL P
LEFT JOIN FEHLTAGE ON (FEHLTAGE_PERSONALID=PERSONAL_ID)

GROUP BY PERSONAL_ID


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:26 Uhr.
Seite 1 von 3  1 23      

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