Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi In SQL Zeitraum abfragen (https://www.delphipraxis.net/216015-sql-zeitraum-abfragen.html)

Uwe Raabe 14. Okt 2024 16:04

AW: In SQL Zeitraum abfragen
 
Zitat:

Zitat von harfes (Beitrag 1542159)
Da alle Veranstaltungen irgendwie vor/in oder in/nach 2024 starten/enden, kann das so nicht funktionieren...

Die Abfrage verknüpft das StartDatum und das EndDatum aber mit AND und nicht mit OR. Insofern sollte eine Veranstaltung im Ergebnis schonmal nicht nach 2024 beginnen und nicht vor 2024 enden. (Das wäre übrigens eventuell auch ein valides Kriterium.)

Könntest du mal konkret die Start- und Ende-Daten der Records auflisten, die deiner Meinung nach nicht im Ergebnis sein sollten?

Übrigens: Deine Abfrage macht meiner Meinung nach auch eine falsche Konvertierung beim übergebenen Jahr (J):
Delphi-Quellcode:
DM1.DataModule1.IBCQuery1.SQL.Add('where ((EXTRACT(YEAR from DatumStart) <= '+QuotedStr(IntToStr(J))+') and (EXTRACT(YEAR from DatumEnde) >= '+QuotedStr(IntToStr(J))+')) ');


Da
SQL-Code:
EXTRACT(YEAR FROM
einen SmallInt zurückgibt, solltest du den nicht mit einem String vergleichen. Versuch es mal ohne die Quotes:
Delphi-Quellcode:
DM1.DataModule1.IBCQuery1.SQL.Add('where ((EXTRACT(YEAR FROM DatumStart) <= '+IntToStr(J)+') and (EXTRACT(YEAR FROM DatumEnde) >= '+IntToStr(J)+')) ');

harfes 14. Okt 2024 16:13

AW: In SQL Zeitraum abfragen
 
mkinzler: ich glaube das war's! Danke.

Allerdings musste ich das anders umsetzen, da die Funktion Last_day wohl erst ab Firebird 4 vorhanden ist...also so habe ich das jetzt gemacht (wobei ComboBox1 eine Auswahliste der Jahre enthält - ComboBox1.Text wäre dann z.B. 2024):

where Datumstart <= '+QuotedStr('31.12.'+ComboBox1.Text)+' and DatumEnde >= '+QuotedStr('01.01.'+ComboBox1.Text)+'

Hartmut

Medium 14. Okt 2024 21:31

AW: In SQL Zeitraum abfragen
 
Zumindest MySQL/MariaDB kennen auch den Operator "between..and". Zusammen mit Parametern ergibt das dann ein gut lesbares Stück Code:

Delphi-Quellcode:
DM1.DataModule1.IBCQuery1.SQL.Text := 'SELECT * FROM `Tabelle` WHERE `Datumsfeld` BETWEEN :dt1 AND :dt2';

DM1.DataModule1.IBCQuery1.ParamByName('dt1').AsDateTime := EncodeDateTime(StrToInt(ComboBox1.Text), 12, 31, 23, 59, 59, 999);
DM1.DataModule1.IBCQuery1.ParamByName('dt2').AsDateTime := EncodeDateTime(StrToInt(ComboBox2.Text), 1, 1, 0, 0, 0,  0);
Damit wäre es dann sogar auf die Millisekunde genau. Falls nicht nötig, gäbe es auch noch EncodeDate(), womit man sich die Uhrzeit-Parameter spart. (Es ist (natürlich...) nicht dokumentiert, aber ich gehe davon aus, dass hier immer die Uhrzeit 00:00:00:0000 implizit zurückgegeben wird.)


Edit: Schon spät. Geht natürlich nur, wenn das Datumsfeld für beide Grenzbedingungen dasselbe ist. Sorry!
Aber Parameter finde ich dennoch deutlich hübscher (und sicherer!)

DeddyH 15. Okt 2024 05:49

AW: In SQL Zeitraum abfragen
 
Kann mir mal irgendjemand erklären, wieso eine zu vergleichende Zahl vor dem Vergleich in einen String gewandelt wird? Nochmal: verwende SQL-Parameter, mit diesem ganzen Gequote bekommst Du nicht nur falsche Ergebnisse, sondern bist auch anfällig für SQL-Injection.
Delphi-Quellcode:
DM1.DataModule1.IBCQuery1.SQL.Text := 'select VERANSTALTUNGSID from VERANSTALTUNGEN where EXTRACT(YEAR from DatumStart) <= :Anfang and EXTRACT(YEAR from DatumEnde) >= :Ende';
DM1.DataModule1.IBCQuery1.ParamByName('Anfang').AsInteger := J;
DM1.DataModule1.IBCQuery1.ParamByName('Ende').AsInteger := J;
Das sollte alle Veranstaltungen liefern, die im betreffenden Jahr begonnen haben oder enden bzw. die das komplette Jahr überlappen.

TigerLilly 15. Okt 2024 06:54

AW: In SQL Zeitraum abfragen
 
Zitat:

die in 2023 gestartet sind und deren Veranstaltung bis irgendwann in 2024 (oder sogar bis 2025)
Ich würde das in vier Teile aufteilen:
- vor JAHR begonnen und nach JAHR beendet
- vor JAHR begonnen und im JAHR beendet
- im JAHR begonnen und nach JAHR beendet
- im JAHR begonnen und im JAHR beendet

Da du alle willst: mit OR verknüpfen. SQL Umsetzung ist dann trivial.

harfes 15. Okt 2024 17:29

AW: In SQL Zeitraum abfragen
 
DeddyH: ja, natürlich sieht das besser und eleganter aus mit Parametern...und kommt bei mir auch beim "Finetuning" - ich wollte nur erstmal testen, ob die Ergebnisse passen, daher die "String-Orgie":oops:.

TigerLilly: das werde ich dann als nächstes testen, damit ich auch wirklich alle Varianten ermitteln kann - danke.

Hartmut

Blup 17. Okt 2024 08:33

AW: In SQL Zeitraum abfragen
 
Im Prinzip werden Veranstaltungen gesucht, deren Zeitraum sich mit einem angegebenen Zeitraum überschneiden.
Das es sich dabei um Jahresanfang und Ende eines bestimmten Jahres handelt, ist nur ein Spezialfall, den man im SQL nicht gesondert behandeln muss.
Sind 'datumstart' und 'datumende' reine Datumsfelder, benötigt man den Zeitanteil bei den Parametern nicht.
Delphi-Quellcode:
var Jahr := StrToInt(ComboBoxJahr.Text);
Query.SQL.Text := 'select * from verabstaltungen where (datumstart <= :bis) and ((datumende is null) or (datumende >= :von))';
Query.ParamByName('von').AsDateTime := EncodeDateTime(Jahr, 1, 1, 0, 0, 0, 0);
Query.ParamByName('bis').AsDateTime := EncodeDateTime(Jahr, 12, 31, 23, 59, 59, 999);


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:02 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz