Entwickler-Ecke
Datenbanken - SQL Abfrage per Quartal
Arne Danikowski - Di 12.05.09 17:43
Titel: SQL Abfrage per Quartal
Hallo,
ich habe in einer Accessdatenbank Datensätze, die nach Datum Indiziert sind.
Aubau der Tabelle:
Feld Art
ID Autowert
Datum Datum (Index)
Kundennummer Integer
Techniker Text
Zeiteinheiten Integer
Bemerkung Memo
Über eine Auswahl (z.B. 2 Comboboxen) soll das Jahr und das Quartal bestimmt werden, wonach die Datensätze gefiltert werden sollen.
Quartal I = 01.01.XX - 31.03.XX
Quartal II = 01.04.XX - 31.03.XX
Quartal III = 01.07.XX - 30.09.XX
Quartal IV = 01.10.XX - 31.12.XX
Ich möchte nun nur Datensätze anzeigen, die folgenden Kreterien entsprechen:
a.) Nur Kundennummer xxx
b.) Jahr aus Combobox I
c.) Quartal aus Combobox II
Also ich bekomme die SQL Abfrage nicht hin. Da ich schon tausend Sachen ausprobiert habe, poste ich hier auch keinen Code.
Vieleicht weis hier jemand Rat.
vd im voraus
ffgorcky - Di 12.05.09 17:55
Naja, ich gehe also mal davon aus, dass Du weißt, wie Du eine SQL-Abfrage an die Datenbank schickst. - Oder liegt das schon daran?
Die Abfrage über die Kundennummer ist doch noch richtig einfach:
SQL-Anweisung
1:
| select * from Automieten where Kundennummer=222 |
...wobei ich denke, dass Du das ganze ja nicht fest Codieren möchtest, also müsstest Du das ganze dann so machen:
Delphi-Quelltext
1:
| SQLQuery:='select * from Automieten where Kundennummer='+EditKundennummer.Value; |
Delete - Di 12.05.09 18:02
Ohne besondere Fehlerbehandlung:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| var y,m1,m2,d1,d2: Word; von, bis: TDate; begin case cbbQuartal.ItemIndex of 0: begin m1 := 1; d1 := 1; m2 := 3; d2 := 31; end; 1: begin m1 := 4; d1 := 1; m2 := 6; d2 := 30; end; 2: begin m1 := 7; d1 := 1; m2 := 9; d2 := 30; end; 3: begin m1 := 10; d1 := 1; m2 := 12; d2 := 31; end; end; y := StrToInt(cbbJahr.Items[cbbJahr.ItemIndex]); von := EncodeDate(y,m1,d1); bis := EncodeDate(y,m2,d2); ADOQuery1.SQL.Text := 'SELECT * FROM Tabelle WHERE (Datum BETWEEN :von AND :bis) AND (Kundennummer=:nr)'; ADOQuery1.Parameters.ParamByName('von').Value := von; ADOQuery1.Parameters.ParamByName('bis').Value := bis; ADOQuery1.Parameters.ParamByName('nr').Value := Kundennummer; ADOQuery1.Open; |
Arne Danikowski - Di 12.05.09 18:20
Vielen Dank für die schnelle Antworten,
habe das mal so gemacht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| procedure Twartungdrucken.BitBtn1Click(Sender: TObject); var y,m1,m2,d1,d2: Word; von, bis: TDate; KDNR:String; begin case qualtalcombo.ItemIndex of 0: begin m1 := 1; d1 := 1; m2 := 3; d2 := 31; end; 1: begin m1 := 4; d1 := 1; m2 := 6; d2 := 30; end; 2: begin m1 := 7; d1 := 1; m2 := 9; d2 := 30; end; 3: begin m1 := 10; d1 := 1; m2 := 12; d2 := 31; end; end; y := StrToInt(JahrCombo.Items[JahrCombo.ItemIndex]); von := EncodeDate(y,m1,d1); bis := EncodeDate(y,m2,d2); KDNR:=DM.EinsatzADOQuery.FieldByName('Kundennummer').AsString; DM.EinsatzADOQuery.SQL.Text := 'SELECT * FROM EINSATZ WHERE (Datum BETWEEN :von AND :bis) AND (Kundennummer=:nr)'; DM.EinsatzADOQuery.Parameters.ParamByName('von').Value := von; DM.EinsatzADOQuery.Parameters.ParamByName('bis').Value := bis; DM.EinsatzADOQuery.Parameters.ParamByName('nr').Value := KDNR; DM.EinsatzADOQuery.Open; RvProject1.Open; RvProject1.Execute; end; |
Allerdings bekomme ich beim Ausführen eine Fehlermeldung:
"Datentypen im Kreterienausdruck unverträglich"
Der Fehler kommt, sobald die Query geöffnet wird.
ffgorcky - Di 12.05.09 18:33
Also ich hätte das dann so gelöst (wobei ich leider nicht weiß, ob das wirklich so eine "saubere" Lösung ist):
Delphi-Quelltext
1:
| DM.EinsatzADOQuery.SQL.Text := 'SELECT * FROM EINSATZ WHERE (Datum BETWEEN '+von+' AND '+bis+') AND (Kundennummer='+KDNR+')'; |
Ich weiß allerdings nicht, ob die Lösung wirklich gut ist, oder doch eher Deine Lösung mit den SQL-Variablen besser ist.
Delete - Di 12.05.09 18:39
Dann versuch es mal mit
Delphi-Quelltext
1: 2:
| DM.EinsatzADOQuery.Parameters.ParamByName('von').AsDate := von; DM.EinsatzADOQuery.Parameters.ParamByName('bis').AsDate := bis; |
[edit] Moment mal, wieso fragst Du die Kundennummer als String ab? Da liegt der Fehler. [/edit]
Arne Danikowski - Mi 13.05.09 09:06
Hallo,
nochmal danke für die Antwort.
AsDate gibt es nicht.
Ich habe aber mal die Daten in String umgewandelt und man siehe es funktioniert.
Der Vollständigkeit das ganze Listing noch einmal:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50:
| procedure Twartungdrucken.BitBtn1Click(Sender: TObject); var y,m1,m2,d1,d2: Word; von, bis: TDate; KDNR,anfang,ende:String; begin case qualtalcombo.ItemIndex of 0: begin m1 := 1; d1 := 1; m2 := 3; d2 := 31; end; 1: begin m1 := 4; d1 := 1; m2 := 6; d2 := 30; end; 2: begin m1 := 7; d1 := 1; m2 := 9; d2 := 30; end; 3: begin m1 := 10; d1 := 1; m2 := 12; d2 := 31; end; end;
y := StrToInt(JahrCombo.Items[JahrCombo.ItemIndex]); von := EncodeDate(y,m1,d1); bis := EncodeDate(y,m2,d2); anfang:=DatetoStr(von); ende:=DateToStr(bis); KDNR:=DM.EinsatzADOQuery.FieldByName('Kundennummer').AsString; DM.EinsatzADOQuery.SQL.Text := 'SELECT * FROM EINSATZ WHERE (Datum BETWEEN :von AND :bis) AND (Kundennummer=:nr)'; DM.EinsatzADOQuery.Parameters.ParamByName('von').Value := anfang; DM.EinsatzADOQuery.Parameters.ParamByName('bis').Value := ende; DM.EinsatzADOQuery.Parameters.ParamByName('nr').Value := KDNR; DM.EinsatzADOQuery.Open; RvProject1.Open; RvProject1.Execute; end; |
Bis dann !! Hat sehr geholfen.
Delete - Mi 13.05.09 09:23
Und wenn Du überall den Cast weglässt (also statt AsString Value verwendest)? Sofern die Kundennummer in beiden Tabellen nummerisch ist, sollte das auch funktionieren.
jaevencooler - Mi 13.05.09 10:25
Guten Tach auch,
also ich bin kein Access Profi, aber auf einer Oracle würde das so gehen :
SELECT * from <<Deiner Tabelle>>
where to_number(to_char(Datum, 'q')) = :Quartal
to_char : wandelt das Datum in einen formatierten String, das Format ist in diesem Fall 'q'
to_number : wandelt das Ergebnis von String in Number (kann amn auch weg lassen und auf String vergleichen.
Die vergelichbaren Routinen sollte es auch in Access geben....
Beste Grüße
Michael
Delete - Mi 13.05.09 10:26
Das sollte aber bei parametrisierten Abfragen im Normalfall gar nicht nötig sein.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!