MSSql Abfrage erstellen (Speziell)

hexe63

Benutzer
Beiträge
10
Hallo erstmal an alle,
ich habe ein Problem eine spezielle Abfrage zu erstellen.
Gegeben ist eine Datenbanktabelle mit den Spalten beginn (Datum), ende (Datum), Dauer in Monaten und weitern für das Problem nicht relevanten Daten.
Gehen wir der einfachheithalber davon aus, es geht um Verträge. Die Vertragslaufzeit Beginnt an einem Datum und endet an einem anderen Datum (Spalten Beginn und Ende). Die Vertragslaufzeiten sind Variabel zwischen 1 Tag und 20 Monaten.

Ich muss eine Abfrage erstellen die alle Datensätze zurück gibt die an einem bestmmten Tag (Wert) innerhalb der Vertragslaufzeit waren.

Ich habe bereits verschiedene Ansätze probiert z.B. between aber hier ist das Problem, dass die Abfrage lauten würde:

Where [ Spaltenname] between [Value1] and [Value2]

Ich bräuchte also etwas in der Art:

Where [ Value / Wert ] between [Spaltenname1 (Beginn) ] and [Spaltenname2 (Ende)]

Kann mir jemand weiterhelfen??


Grüße aus Berlin

Bleibt alle Gesund
 
Werbung:
Code:
edb=*# create table hexe63(id int generated always as identity primary key, begin date, ende date);
CREATE TABLE
edb=*# insert into hexe63 (begin, ende) values (current_date - 100, current_date + 100);
INSERT 0 1
edb=*# insert into hexe63 (begin, ende) values (current_date + 100, current_date + 200);
INSERT 0 1
edb=*# select * from hexe63 where current_date > begin and current_date < ende;
 id |       begin        |        ende        
----+--------------------+--------------------
  1 | 11-OCT-21 00:00:00 | 29-APR-22 00:00:00
(1 row)

edb=*# select * from hexe63 where '2022-05-01'::date > begin and '2022-05-01'::date < ende;
 id |       begin        |        ende        
----+--------------------+--------------------
  2 | 29-APR-22 00:00:00 | 07-AUG-22 00:00:00
(1 row)

edb=*#
 
Hallo, danke dir erstmal.

Leider verstehe ich "Bahnhof"!

Was ich verstehe:

in den ersten 6 Zeilen erstellst due eine Testdatenbank.
Ausgehend vom aktuellen Datum 100 Datensätze mit täglichen Datumsangaben für Beginn rückwärts und für ende vorwärts
Weiterhin 100 Datensätze beginnend mit aktuellem Datum für Beginn vorwärts und 200 für ende vorwärts.

Deine Selectabfragen verstehe ich nicht, bitte erläutern.

Zumindest bei der ersten Select abfrage würde ich erwarten, dass 100 Datensätze zurückgegeben werden, da ausgehend vom aktuellen Datum ja alle 100 erstellten Datensätze in den Abfragezeitraum fallen würden.

Wie geschrieben, ich brauche ALLE Datensätze bei denen das gesuchte Datum zwischen dem Wert der Spalte Beginn und dem Wert der Spalte ende ist.

Gruß Aus Berlin
 
Hallo, danke dir erstmal.

Leider verstehe ich "Bahnhof"!

Was ich verstehe:

in den ersten 6 Zeilen erstellst due eine Testdatenbank.

nein, eine Tabelle mit 2 Testdatensätzen.


Ausgehend vom aktuellen Datum 100 Datensätze mit täglichen Datumsangaben für Beginn rückwärts und für ende vorwärts
Weiterhin 100 Datensätze beginnend mit aktuellem Datum für Beginn vorwärts und 200 für ende vorwärts.

Nein, 2 Datensätze, einmal von heute - 100 Tage bis heute + 100 Tage, der andere von heute + 100 bis heute + 200

Deine Selectabfragen verstehe ich nicht, bitte erläutern.

Zumindest bei der ersten Select abfrage würde ich erwarten, dass 100 Datensätze zurückgegeben werden, da ausgehend vom aktuellen Datum ja alle 100 erstellten Datensätze in den Abfragezeitraum fallen würden.

es kann nur zurückgegeben werden was vorher gespeichert wurde...

Wie geschrieben, ich brauche ALLE Datensätze bei denen das gesuchte Datum zwischen dem Wert der Spalte Beginn und dem Wert der Spalte ende ist.

Gruß Aus Berlin

Einfacher als das schon gezeigte wäre diese Lösung:

Code:
edb=*# create table demo (id int generated always as identity, von_bis daterange);
CREATE TABLE
edb=*# insert into demo (von_bis) values ('[2022-01-01,2022-01-02)');
INSERT 0 1
edb=*# insert into demo (von_bis) values ('[2022-02-01,2022-02-28)');
INSERT 0 1
edb=*# insert into demo (von_bis) values ('[2022-01-01,2022-01-31)');
INSERT 0 1
edb=*# insert into demo (von_bis) values ('[2022-01-01,2022-02-28)');
INSERT 0 1
edb=*# select * from demo;
 id |         von_bis         
----+-------------------------
  1 | [2022-01-01,2022-01-02)
  2 | [2022-02-01,2022-02-28)
  3 | [2022-01-01,2022-01-31)
  4 | [2022-01-01,2022-02-28)
(4 rows)

edb=*# select * from demo where von_bis @> current_date;
 id |         von_bis         
----+-------------------------
  3 | [2022-01-01,2022-01-31)
  4 | [2022-01-01,2022-02-28)
(2 rows)

Das verwendet DATERANGE-Daten. Da läßt sich via @> z.B. prüfen, ob ein Datum innerhalb dieser Range liegt.
 
Danke für deine Antwort,
ich wollte mich gerade selber korrigieren, da mir gerade selber aufgegangen ist, dass ich bullshit geschrieben habe.

Du denkst schon daran, dass es um einen MSSQL Server geht?

Den "Daterange" Datentyp gibt es da meines Wissens nach nicht
 
dann gehe ich davon aus, dass dein erster Post auch Postgres ist und auf MSSQL nicht anwendbar.

Hast du eventuell eine Idee wie es , gerne auch mit Umwegen, Darstellbar ist?

Wenn nicht danke ich dir erstmal für deine mühe, bleib Gesund.

Gibt es eventuell jemand anderen der mir weiterhelfen kann?
 
hast Du es denn hinbekommen? Zuerst hast Du geschrieben:

Ich bräuchte also etwas in der Art:
Where [ Value / Wert ] between [Spaltenname1 (Beginn) ] and [Spaltenname2 (Ende)]

diese Syntax gibt es nicht, man kann aber schauen, ob der Wert größer Spalte1 und kleiner Spalte2 ist. Kannst Du soweit folgen?
 
Leider bisher nicht hinbekommen.

Das wäre ja dann

@Date= "01.10.2021

WHERE ([Beginn] >= @Date) OR ([Ende] <= @Date)

würde dann aber mehr oder weniger alle Datensätze betreffen, da jeweils das ausschließende Kriterium fehlen wurde

Bei einer Variante

WHERE ( ([Beginn] >= @Date) and ([Ende] <= @Date) ) OR (([Ende] <= @Date) and ([Beginn] >= @Date))

würden Zwischenwerte nicht berücksichtigt
 
neben der logischen Verknüpfung von OR (eine Bedingung muß wahr sein) gibt es auch noch AND, bei der beide Bedingungen wahr sein müssen. Daher habe ich das auch in meinem ersten Post verwendet ...
 
Du meinst

WHERE ([Beginn] >= @Date) AND ([Ende] <= @Date)

Geht auch nicht, da Zeitraume bei denen @Date zwischen Beginn und ende Liegen nicht berücksichtigt werden.

Beispiel:

Vertrag beginnt am 01.01.2021 (Beginn) und endet am 31.12.2021 (Ende) ich möchte wissen, ob der Vertrag am 01.10.2021 (@Date) aktiv ist.

Bedingung 1 ([Beginn] >= @Date) Datum Beginn ist größer Gleich 01.10.2021. Bedingung ist falsch
Bedingung 2 ([Ende] <= @Date) Datum Ende ist kleiner Gleich 01.10.2021. Bedingung ist wahr

Bedingung1 AND Bedingung2 Bedingung ist falsch, da Bedingung1 falsch ist. Der Datensatz würde nicht ausgegeben. Wir hingegen sagen der Vertrag ist am 01.10.2021 aktiv (weil zwischen dem 01.01.2021 und dem 31.12.2021) der Datensatz müßte ausgegeben werden.
 
hast Du es denn hinbekommen? Zuerst hast Du geschrieben:



diese Syntax gibt es nicht, man kann aber schauen, ob der Wert größer Spalte1 und kleiner Spalte2 ist. Kannst Du soweit folgen?
Kommando zurück...

Code:
edb=*# select * from hexe63;
 id |        begin        |        ende         
----+---------------------+---------------------
  1 | 2021-10-12 00:00:00 | 2022-04-30 00:00:00
  2 | 2022-04-30 00:00:00 | 2022-08-08 00:00:00
(2 rows)

edb=*# select * from hexe63 where '2021-08-30'::date between begin and ende;
 id | begin | ende 
----+-------+------
(0 rows)

edb=*# select * from hexe63 where '2021-11-30'::date between begin and ende;
 id |        begin        |        ende         
----+---------------------+---------------------
  1 | 2021-10-12 00:00:00 | 2022-04-30 00:00:00
(1 row)

edb=*# select * from hexe63 where '2022-01-30'::date between begin and ende;
 id |        begin        |        ende         
----+---------------------+---------------------
  1 | 2021-10-12 00:00:00 | 2022-04-30 00:00:00
(1 row)

edb=*# select * from hexe63 where '2022-05-30'::date between begin and ende;
 id |        begin        |        ende         
----+---------------------+---------------------
  2 | 2022-04-30 00:00:00 | 2022-08-08 00:00:00
(1 row)

edb=*# select * from hexe63 where '2022-12-30'::date between begin and ende;
 id | begin | ende 
----+-------+------
(0 rows)

edb=*#
 
Werbung:
Tja, die Welt wäre besser wenn alle Datenbanken so gut wie PostgreSQL wären, aber dennoch denke ich, in der Form

select ... from ... where DATUM > begin and DATUM < ende

sollte es funktionieren...
 
Zurück
Oben