Hi,
ich denke es ist durchaus manchmal notwendig im "ON" außer der Join- auch
andere Bedingungen anzugeben.
folgendes Bsp.
Gesucht sind ALLE Personen mit der Anzahl der zugeordneten Verträge:
SQL-Code:
select
P.ID,
P.PERSONEN_NAME,
count(A.ID)
from
PERSON P
left join EAUFTRAG A on (A.PATIENT_ID = P.ID)
group by
P.ID,
P.PERSONEN_NAME
Im Ergebnis erhält man alle Personen in der Anzahl zugeordnete Verträge,
inclusive der Personen mit 0 Aufträgen.
Wenn man jetzt wieder ALLE Personen und die Anzahl Verträge alledings
begrenzt auf das einen Zeitraum (z.B. 2007) sehen will, könnte man
als Erstes auf die Idee kommen einfach in der Where-Klausel den
Zeitraum der Auftrage einzugrenzen:
SQL-Code:
select
P.ID,
P.PERSONEN_NAME,
count(A.ID)
from
PERSON P
left join EAUFTRAG A on (A.PATIENT_ID = P.ID)
where
(A.DATUM_VON between '01.01.2007' and '31.12.2007')
group by
P.ID,
P.PERSONEN_NAME
Damit bekommt man jetzt zwar alle Personen die mindestens eine Vertrag
in 2007 haben, aber alle anderen Personen ohne Vertrage (count(A.ID) = 0) fehlen!
Warum? Weil in der "verjointen" Ergebnismenge, über diese wird das count() ausgeführt,
nur Daten enthalten sind für die
(A.DATUM_VON between '01.01.2007' and '31.12.2007') zutrifft.
Mit dieser Bedingung wird das "left join" sozusagen ausgehebelt.
Gut, also müssen in der "verjointen" Ergebnismenge auch Datensätzen mit
A.DATUM_VON is NULL,
also Personen ohne Vertrag, enthalten sein.
Die Where-Klausel wird erweitert:
SQL-Code:
select
P.ID,
P.PERSONEN_NAME,
count(A.ID)
from
PERSON P
left join EAUFTRAG A on (A.PATIENT_ID = P.ID)
where
A.DATUM_VON is null or (A.DATUM_VON between '01.01.2007' and '31.12.2007')
group by
P.ID,
P.PERSONEN_NAME
Damit erhält man genau das gewünschte Ergebnis:
Alle Personen mit der Anzahl Verträge im Jahr 2007 incl. Personen ohne Verträge.
Wenn man sich jetzt (z.B. im IBExpert) die Anzahl der Read-Zugriffe ansieht,
erhält man im Beispiel
Person, nicht indiziert Reads: 167
EAuftrag, indiziert Reads: 644
Stellt man jetzt aber die
SQL um, in dem man bereits im "..ON.." den Zeitraum einschränkt:
SQL-Code:
select
P.ID,
P.PERSONEN_NAME,
count(A.ID)
from
PERSON P
left join EAUFTRAG A on (A.PATIENT_ID = P.ID and A.DATUM_VON between '01.01.2007' and '31.12.2007')
group by
P.ID,
P.PERSONEN_NAME
so erhält man die gleiche Ergebnismenge aber mit folgende Read-Zugriffe:
Person, nicht indiziert Reads: 167
EAuftrag, indiziert Reads: 65
Warum?
Weil die Anzahl der Daten aus EAUFTRAG bereits VOR dem JOIN eingeschränkt wurde!
Es müssen also erheblich weniger Daten gezählt werden.
alex