(MySQL) überschneidende Einträge filtern?
klaus
- datenbank
0 Ilja0 Klaus0 Frank (no reg)0 klaus
0 Ilja
Hallo,
ich habe einen Urlaubsplaner für die Mitarbeiter. In einer Tabelle stehen die Abwesenheiten, in einer Tabelle steht die Abwesenheitsarten (z.B. auch Schulung, Geschäftsreise, ...) mit den entsprechenden Farben und in einer Tabelle die Feiertage.
Diese möchte ich nun kombiniert anzeigen lassen.
Ich möchte nun aber diejenigen Feiertage aus der Ergebnisliste filtern, die in einen Urlaubseintrag fallen würden.
Nur wie könnte ich das bewerkstelligen?
Habt ihr vielleicht eine Idee?
Meine bisherige Abfrage sieht also wie folgt aus:
select
a.idnr,a.bestaetigt,a.urlaubvon,a.urlaubbis,
a.halbertag,c.bezeichnung,c.farbe
from urlaubdaten as a left join urlaubarten as c on a.artnr = c.artnr
where a.personalnummer='$personalnummer' AND a.urlaubvon like '$zeitraum-%' AND a.geloescht <> 'J'
UNION select
'','J',feiertag AS urlaubvon,feiertag AS urlaubbis,'',
feiertag_text AS bezeichnung,'gelb'
from feiertage
where feiertag like '2007%' order by urlaubvon
yo,
warum der LEFT JOIN in der ersten abfrage, gibt es den abwesenheiten in der tabelle urlaubsdaten die keinen entsprechenden eintrag für die urlaubsart haben ?
was dein problem angeht, mach einen JOIN der drei tabellen und als JOIN bedingung nimmst du du das datum des feiertages und schauchst mit dem BETWEEN Operator, ob dieser in einem urlaub fällt.
SELECT ...
FROM urlaubdaten a
INNER JOIN feiertage f ON f.feiertag BETWEEN a.urlaubvon AND a.urlaubbis
INNER (LEFT) JOIN urlaubarten c ON a.artnr = c.artnr
Ilja
Hallo Ilja,
vielen Dank für Deine schnelle Antwort. Ich bin aber gerade erst zurück an meinen PC.
was dein problem angeht, mach einen JOIN der drei tabellen und als JOIN bedingung nimmst du du das datum des feiertages und schauchst mit dem BETWEEN Operator, ob dieser in einem urlaub fällt.
SELECT ...
FROM urlaubdaten a
INNER JOIN feiertage f ON f.feiertag BETWEEN a.urlaubvon AND a.urlaubbis
INNER (LEFT) JOIN urlaubarten c ON a.artnr = c.artnr
Wenn ich Deine Abfrage ausprobiere, erhalte ich lediglich den Eintrag zurück, der sich mit einem Feiertag überschneidet. Ich möchte aber doch genau die andere Menge, alle, wo sich kein Feiertag überschneidet.
Hi
Wenn ich Deine Abfrage ausprobiere, erhalte ich lediglich den Eintrag zurück, der sich mit einem Feiertag überschneidet. Ich möchte aber doch genau die andere Menge, alle, wo sich kein Feiertag überschneidet.
Dann (Tipp ins Dunkelgrüne) benutzt du einen FULL OUTER JOIN und prüfst beide Seiten (geeignete Spalten beider ge-jointen Tabellen) auf NULL.
Ciao, Frank
Hallo Frank,
Dann (Tipp ins Dunkelgrüne) benutzt du einen FULL OUTER JOIN und prüfst beide Seiten (geeignete Spalten beider ge-jointen Tabellen) auf NULL.
Wenn ich INNER JOIN durch ein OUTER JOIN ersetze, schmeisst's mir einen SQL-Fehler raus.
Wenn ich statt dem BETWEEN ein NOT BETWEEN schreibe, erhalte ich dummerweise auch alle die Einträge, die nicht der Personalnummer und nicht dem Datumsbereich betreffen.
Vielleicht kannst Du (grob) skizzieren, wie der select aussieht, kann auch sein, dass ich Dir einfach nicht folgen konnte.
wie wäre es mit deinem konkreten SQL, was du jetzt gebaut hast und der konkreten Fehlermeldung, die es dir schmeisst?
Frank
yo,
Ich möchte aber doch genau die andere Menge, alle, wo sich kein Feiertag überschneidet.
ok, dann habe ich das mit dem filtern falsch aufgefasst, ich dachte, genau diese wolltest du haben. Hier also der andere fall:
SELECT ...
FROM urlaubdaten a
INNER (LEFT) JOIN urlaubarten c ON a.artnr = c.artnr
WHERE NOT EXISTS (SELECT NULL
FROM feiertage f
WHERE f.feiertag BETWEEN a.urlaubvon AND
a.urlaubbis
)
;
Ilja
Hallo Ilja,
SELECT ...
FROM urlaubdaten a
INNER (LEFT) JOIN urlaubarten c ON a.artnr = c.artnr
WHERE NOT EXISTS (SELECT NULL
FROM feiertage f
WHERE f.feiertag BETWEEN a.urlaubvon AND
a.urlaubbis
)
;
Das hab ich jetzt mal daraus gebastelt.
Sieht fast gut aus, aber jetzt wird auch der Urlaub, in den ein Feiertag fällt, herausgefiltert. Ich möchte ja nur den Feiertag, sofern in eine Urlaubszeit fällt, herausgenommen haben.
SELECT a.idnr, a.bestaetigt, a.urlaubvon, a.urlaubbis, a.halbertag, c.bezeichnung, c.farbe
FROM urlaubdaten a
INNER JOIN urlaubarten c ON a.artnr = c.artnr
WHERE a.personalnummer = '3122'
AND a.urlaubvon LIKE '2007-%'
AND a.geloescht <> 'J'
AND NOT
EXISTS (SELECT NULL
FROM feiertage f
WHERE f.feiertag
BETWEEN a.urlaubvon
AND a.urlaubbis)
ORDER BY urlaubvon
yo,
schwere geburt und mir ist noch nicht ganz klar, was du willst. du willst nur die feiertage anzeigen lassen, welche nicht in einem urlaub liegen ?
dann musst du das ganze enfach umdrehen, nämlich die äußere abfrage nach innen und die inner unterabfrage nach aussen und wieder mit dem NOT EXISTS verbinden.
wenn das immer noch nicht das ist was du wills,t solltest du am besten mal beispiele mit daten ausgeben, welche ausgangsdaten hast du, welche willst du ausgeben lassen.
Ilja
Hallo Ilja,
ich glaube, ich habe es (dank Deiner Hilfe) selber hinbekommen.
Meine letzter Stand der Abfrage sieht jetzt wie folgt aus:
Sieht zwar reichlich komplex aus, aber besser habe ich es (bisher) nicht gelöst bekommen.
SELECT a.idnr, a.bestaetigt, a.urlaubvon, a.urlaubbis, a.halbertag, c.bezeichnung, c.farbe
FROM urlaubdaten AS a
LEFT JOIN urlaubarten AS c ON a.artnr = c.artnr
WHERE a.personalnummer = '3122'
AND a.urlaubvon LIKE '2007-%'
AND a.geloescht <> 'J'
UNION SELECT '', 'J', f.feiertag AS urlaubvon, f.feiertag AS urlaubbis, '', f.feiertag_text AS bezeichnung, 'gelb'
FROM feiertage f
WHERE f.feiertag LIKE '2007-%'
AND NOT
EXISTS (
SELECT g.idnr
FROM urlaubdaten g
WHERE g.personalnummer = '3122'
AND g.urlaubvon LIKE '2007-%'
AND g.geloescht <> 'J'
AND f.feiertag
BETWEEN g.urlaubvon
AND g.urlaubbis
)
ORDER BY urlaubvon