Archiv verlassen und diese Seite im Standarddesign anzeigen : SQL: mehrere Daten (Zeiträume) abfragen
Tyrann
2003-06-24, 15:12:16
ich möchte in einer sql abfrage mehrere zeiträume abfragen
beispiel:
select name, nummer from tabelle
where datum between '01.jan.02' and '01.mar.02'
and datum between '01.apr.02' and '01.jun.02'
and datum between '01.jul.02' and '01.sep.02';
wie kann ich sowas bewerkstelligen ?
orginal:
select gsk, wbaugruppe.zeitbaust,wbaugruppe.gruppe_bg, count (*)
from wbaugruppe,wmodul
where wbaugruppe.zeitbaust like 'A3'
and ptadat between '01.JAN.02' and '01.JAN.03'
and wmodul.bg_id_ein=wbaugruppe.bg_id
group by gsk,wbaugruppe.zeitbaust,gruppe_bg
order by gsk;
HellHorse
2003-06-24, 15:32:53
Ich würde das Datum korrekt fromatieren, aber sonst sollte es gehen. Habs bei mir mit MySQL 4 probiert und es funzt.
Vermutlich wolltest du OR statt AND schreiben ;-)
stabilo_boss13
2003-06-24, 15:56:33
Eigentlich müsste das so heissen:
select irgendwas from tabelle where
(datum between startdatum1 and enddatum1) or (datum between startdatum2 and enddatum2)
usw.
Schneller sollte es so gehen:
select irgendwas from tabelle where
datum between startdatum1 and enddatum1
union all
select irgendwas from tabelle where
datum between startdatum2 and enddatum2
usw.
HellHorse
2003-06-24, 16:57:12
......
Schneller sollte es so gehen:
select irgendwas from tabelle where
datum between startdatum1 and enddatum1
union all
select irgendwas from tabelle where
datum between startdatum2 and enddatum2
usw.
[/SIZE]
Wieso schneller? Es werden ja mehrere temporäre Tabellen erstellt.
Tyrann
2003-06-24, 17:37:29
nein, das sollte schon and heisen
zum schluss soll eine tabelle rauskommen die in etwa so aussieht
typ|anzahl zeitraum 1|anzahl zeitraum2|anzahl zeitraum3
-------------------------------------------------------
..d.|..........1...........|..........0...........|.......5
..a.|..........3...........|..........4...........|.......9
das mit dem datum passt schon so bei oracle.
und mein beispiel war vielleicht nicht ganz komplett aber
der original-select funtioniert so wie er ist, mir fehlen
halt nur die anderen zeiträume
Original geschrieben von Tyrann
nein, das sollte schon and heisen
Da kannst du ganz sicher nicht And verwenden.
datum between '01.jan.02' and '01.mar.02'
and datum between '01.apr.02' and '01.jun.02'
and datum between '01.jul.02' and '01.sep.02'
ist immer falsch, weil das Datum nicht gleichzeitig in drei verschiedenen Zeiträumen liegen kann. Und eine And-Verknüpfung ist nur dann wahr, wenn alle Teile wahr sind.
HellHorse
2003-06-24, 19:00:28
Original geschrieben von Tyrann
nein, das sollte schon and heisen
zum schluss soll eine tabelle rauskommen die in etwa so aussieht
typ|anzahl zeitraum 1|anzahl zeitraum2|anzahl zeitraum3
-------------------------------------------------------
..d.|..........1...........|..........0...........|.......5
..a.|..........3...........|..........4...........|.......9
das mit dem datum passt schon so bei oracle.
und mein beispiel war vielleicht nicht ganz komplett aber
der original-select funtioniert so wie er ist, mir fehlen
halt nur die anderen zeiträume
Das ist jetzt aber etwas anderes. So wie ich das sehe möchtest du wissen, wieviele records in den einzelnen Zeiträumen liegen.
Tyrann
2003-06-24, 19:08:28
@HellHorse, du hast den Finger drauf !
stabilo_boss13
2003-06-24, 21:27:34
Original geschrieben von HellHorse
Wieso schneller? Es werden ja mehrere temporäre Tabellen erstellt. Erfahrung: Oft ist eine Abfrage auf einem SQL-Server schneller, wenn man union statt or benutzt. Kommt aber auf die Komplexität der Abfrage an.
Original geschrieben von Xmas
Da kannst du ganz sicher nicht And verwenden.
datum between '01.jan.02' and '01.mar.02'
and datum between '01.apr.02' and '01.jun.02'
and datum between '01.jul.02' and '01.sep.02'
ist immer falsch, weil das Datum nicht gleichzeitig in drei verschiedenen Zeiträumen liegen kann. Und eine And-Verknüpfung ist nur dann wahr, wenn alle Teile wahr sind. Da muss ich mich Xmas anschließen. Mir ist noch nicht klar, wie der Select funktioneren soll.
Die Abfrage
select irgendwas from tabelle where farbe=rot and farbe=blau
gibt niemals einen Datensatz zurück, da Farbe ja unmöglich gleichzeitg rot und blau sein kann. Genauso wenig kann ein Datum gleichzeitig zwischen dem 1.1.2000 und 31.1.2000 und zwischen dem 1.5.2000 und 30.5.2000 liegen.
Wenn ich dich richtig verstanden habe, soll dein Select ja so aussehen:
select gsk, wbaugruppe.zeitbaust,wbaugruppe.gruppe_bg, count (*)
from wbaugruppe,wmodul
where wbaugruppe.zeitbaust like 'A3'
and ptadat between '01.JAN.02' and '31.JAN.02'
and ptadat between '01.FEB.02' and '28.FEB.02'
and ptadat between '01.MAR.02' and '31.MAR.02'
and wmodul.bg_id_ein=wbaugruppe.bg_id
group by gsk,wbaugruppe.zeitbaust,gruppe_bg
order by gsk;
Oder hab ich da was übersehen?
HellHorse
2003-06-24, 21:42:34
Original geschrieben von Tyrann
@HellHorse, du hast den Finger drauf !
Falls dem wirklich so ist machst du am einfachsten eine temporäre Relation (mit WITH oder AS im FROM) für jeden Zeitraum, in der typ (oder wie der Primärschlüssel auch heisst) und das Datum steht. Im SELECT zählst du dann einfach wie oft der typ in jedem Zeitraum vorkommt.
Hässlich aber es sollte gehen.
Falls das die Frage nicht beantwortet hat, könntest du das Schemadiagramm posten?
grakaman
2003-06-24, 21:44:24
Na, er will für jeden Zeitraum die Anzahl der Datensätze haben. Also mit mehreren Aggregat Funktionen im Select, wenn ich das richtig verstanden habe. Ich hab auch schon mal versucht ein join auf ein und die selbe Tabelle zu machen, aber da liefert er mir auch immer nur komische Werte von der Aggregatfunktion zurück.
MfG
Tyrann
2003-06-24, 21:51:40
@HellHorse das beantwortet meine Frage,
aber was ist eine tempöräre Relation ? :grübel:
könntest du mir mal ein einfaches kurzes Beispiel geben ?
ich bin nicht so der SQL Crack
HellHorse
2003-06-25, 00:59:08
Folgende Situation:
Wir haben eine Relation baume, die unter anderem das Attribut baum_id hat, das Primärschlüssel ist (hier werden die Bäume gespeichert). Zudem habem wir die Relation schneidungen, die die Attributte baum_id (foreign key) und schneidungsdatum hat (hier wird für jeden Baum gespeichert wann er geschnitten wurde). Wir wollen für jedem Baum wissen, wie oft wer von zeit1 bis zeit2, zeit3 bis zeit4 und zeit5 bis zeit 6 geschnitten wurde.
Hoffe das trifft dein Problem in etwa.
WITH schneidung1 (baum_id, anzahl1) AS
SELECT DISTINCT baum_id, COUNT (DISTINCT baum_id)
FROM schneidungen
WHERE schneidungsdatum BETWEEN zeit1 AND zeit2
GROUP BY baum_id
WITH schneidung2 (baum_id, anzahl2) AS
...
WITH schneidung3 (baum_id, anzahl3) AS
...
SELECT baum_id, anzahl1, anzahl2, anzahl3
FROM baume FULL INNER JOIN schneidung1 ON (schneidung1.baum_id = baume.baum_id) FULL INNER JOIN ...;
Ich weiss nicht, wie die Dinger richtig heissen aber schneidung1 bis schneidung3 sind Relationen, die nur für dieses Query existieren und daher sage ich ihnen temporär.
Edit:
ein Fehler weniger
Tyrann
2003-06-25, 10:30:00
@HellHorse:
funktioniert die Abfrage auch unter Oracle 8 ?
bei mir wills irgendwie nicht
du hast ausserdem das GROUP BY an der falschen Stelle gehabt, das muss hinters WHERE.
wäre nicht schlecht wenn da noch jemand ne idee hat, sonst muss ich die Daten hinterher in meinem Programm zusammenführen, was aber aufwendig wird (Centura)
HellHorse
2003-06-25, 12:27:21
Ist vermutlich nicht der einzige Fehler ;)
Hmm soviel ich weiss, kennt 8i keine joins (bin mir aber nicht sicher, falls es stimmt ist es eine Frechheit).
Ev unterstützt es auch das WITH nicht.
Workaround für fehlendes WITH . Im FROM fügst du ein
(SELECT DISTINCT baum_id, COUNT (DISTINCT baum_id)
FROM schneidungen
WHERE schneidungsdatum BETWEEN zeit1 AND zeit2
GROUP BY baum_id) AS schneidung1 (baum_id, anzahl1), ...
Analog für die anderen.
Workaraound für den fehlenden join, füge im WHERE
baume.baum_id = schneidung1.baum_id AND baume.baum_id = schneidung2.baum_id AND,...
hinzu.
Edit:
Sah gereade, dass es so wohl nicht hinhaut, wenn ein Baum im einem bestimmten Zeitraum nicht geschnitten wurde. Deshalb neu:
(baume.baum_id = schneidung1.baum_id OR baume.baum_id NOT IN schneidung1.baum_id) AND ...
Jetzt musst du nur noch mit null Werten und doppelten rows aufpassen, d.h. du machst am besten aus SELECT ein SELECT DISTINCT.
Edit2:
Das oben genannte Problem triff nicht auf, wenn ein Baum in einem Zeitraum nicht geschnittten wurde, sondern überhaupt nie geschnitten wurde.
Baue das Query am besten schrittweise auf, damit die Fehler schneller erkennst.
vBulletin®, Copyright ©2000-2025, Jelsoft Enterprises Ltd.