MSSQL 2000 / WHERE liefert ein paar Duplikate / Duplikate in Query Ergebnis gleich rauslassen
Der Biber wird sich jetzt wieder an VERENDE festbeissen, aber......
folgendes:
prüft ob ein Vertrag noch läuft, oder ob er ein NULL Wert enthält, dann ist es ein Vertrag ohne Enddatum. Eigentlich sollen beide Arten im Ergebnis erscheinen, aber jedoch nur einmal für eine Person.
Bedingung: wenn eine Person 2 Verträge hat, dann soll der mit dem NULL Wert genommen werden.
Die Personen werden wie folgt abgefragt:
Ich hab es mit UNION versucht, indem ich die o.g. Prüfung 2 geteilt hab. Hat aber nicht geklappt. Duplikate waren danach immernoch vorhanden.
HILFE!
folgendes:
WHERE ( (VERTRAG.VERENDE IS NULL OR VERTRAG.VERENDE>= Getdate())
prüft ob ein Vertrag noch läuft, oder ob er ein NULL Wert enthält, dann ist es ein Vertrag ohne Enddatum. Eigentlich sollen beide Arten im Ergebnis erscheinen, aber jedoch nur einmal für eine Person.
Bedingung: wenn eine Person 2 Verträge hat, dann soll der mit dem NULL Wert genommen werden.
Die Personen werden wie folgt abgefragt:
SELECT
PGRDAT.ZIMMER as "wic_uid"
FROM L2001.PGRDAT PGRDAT
Ich hab es mit UNION versucht, indem ich die o.g. Prüfung 2 geteilt hab. Hat aber nicht geklappt. Duplikate waren danach immernoch vorhanden.
HILFE!
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 48016
Url: https://administrator.de/forum/mssql-2000-where-liefert-ein-paar-duplikate-duplikate-in-query-ergebnis-gleich-rauslassen-48016.html
Ausgedruckt am: 24.12.2024 um 12:12 Uhr
5 Kommentare
Neuester Kommentar
Moin flasch-gordon,
nachdem Du ja das Umlaut-Problem selbst in den Griff bekommen hast, würde ich ja gern hier mit an einer Lösung basteln.
Grundsätzlich würde dieses Theater mit diesem VERRECKE/VERENDE-Feld gar nicht so massiv auftreten, wenn Ihr in Eurer DB von vornherein mit einem Dummy-Wert von "31.12.9999" oder ähnlich für "Kein Vertragsende festgelegt" gearbeitet hättet.
Dann ließe sich hier wie auch im letzten Thread ganz einfach mit Max() selektieren.
So bleibt als zweitbeste Variante wirklich nur ein UNION.
Verbal / Pseudo-SQL:
Was hier noch fehlt, sind die zusätzlichen WHERE-Bedingungen, die die VERTRAG und die PGRDAT-Tabelle miteinander verbinden.
Also bitte nicht so abschicken, sonst hast Du mit Sicherheit ein kartesisches Produkt.
Wie hängen die beiden denn zusammen?
Gruß
Biber
P.S. PGRDAT ist auch ein schöner Tabellenname- habt er den Kram 1:1 von dBaseIII migriert?
nachdem Du ja das Umlaut-Problem selbst in den Griff bekommen hast, würde ich ja gern hier mit an einer Lösung basteln.
Grundsätzlich würde dieses Theater mit diesem VERRECKE/VERENDE-Feld gar nicht so massiv auftreten, wenn Ihr in Eurer DB von vornherein mit einem Dummy-Wert von "31.12.9999" oder ähnlich für "Kein Vertragsende festgelegt" gearbeitet hättet.
Dann ließe sich hier wie auch im letzten Thread ganz einfach mit Max() selektieren.
So bleibt als zweitbeste Variante wirklich nur ein UNION.
Verbal / Pseudo-SQL:
Select .... from Vertrag, PGRDAT
WHERE ( VERTRAG.VERENDE>= Getdate() AND ...[PGRDAT-VERTRAG-Verknüpfung])
UNION
Select .... from Vertrag, PGRDAT
WHERE ( (VERTRAG.VERENDE IS NULL AND ...[PGRDAT-VERTRAG-Verknüpfung]
And PGRDAT.ZIMMER NOT in (
Select PGRDAT.ZIMMER from Vertrag, PGRDAT
WHERE ( VERTRAG.VERENDE>= Getdate() AND ....)
)
Also bitte nicht so abschicken, sonst hast Du mit Sicherheit ein kartesisches Produkt.
Wie hängen die beiden denn zusammen?
Gruß
Biber
P.S. PGRDAT ist auch ein schöner Tabellenname- habt er den Kram 1:1 von dBaseIII migriert?
Umso besser, flash-gordon,
Wenn Du es ausgeknobelt hast.
Bei SQL-Statements sind bei mir oft auch die Grenzen der Abstraktionsfähigkeit erreicht - ganz ohne Probieren alles einfach runterschreiben mach ich da ungern.
Drei Sachen wollte ich noch anregen:
- das Zeitverhalten dieser Abfrage dürfte absolut grottig sein. Ich empfehle Dir nochmal die Prüfung (und ggf. interne Diskussion), ob ihr für diesen Vertrags-Ablauf einen definierten HIGHVALUE-Wert einführen könnt (also ein "Monddatum" 31.12.2099 oder 31.12.9999).
Wenn es die Client-Appz weiß (und genau diesen Wert prüfen und richtig interpretieren kann), dann wäre es SQL-technisch wesentlich einfacher, performanter und wartbarer. Und ob Du ein "offenes Vertragsende" anzeigst als "00000000" oder "99991231"... das ist beides gleich hässlich.
- Plan B: Wenn das nicht geht, weil ihr da noch irgendwelche Lizenzknebeln bis zum Jahr 2023 habt mit dieser DB und da nix Großes ändern dürft, dasn würde ich dieses Statement nicht Clientseitig zusammenschroten und über die Leitung schicken, sondern die Arbeit durch eine kleine Stored Procedure serverseitig abfackeln. Bringt erstens eine Menge Performance und zweitens, so wie diese DB aussieht, ist einer der Grundgedanken von sauberen SQL-Schnittstellen verletzt: jede doofe Client-Application muss bis ins letzte physikalische Detail die Tabellenstrukturen und -relationen kennen. Das kostet nicht nur Performance, sondern auch richtig Geld - weil die ganze Logik clientseitig nachgekaspert bzw. entwickelt werden muss.
Dann lieber ein STP GibMirAlleAktuellenVerträge() mt einem definierten Resultset und gut.
- und wo ich mir ja schon vorhin auf die Lippen gebissen habe.... ääähm... hat diese DB denn auch so etwas wie VIEWs oder gar ein logisches Datenmodell? Solche Statements wie oben sind ja hart der Grenze der Wartbarkeit - ich würde diese ganzen verknibbelten Statements, also beispielsweise alles im ersten SELECT... FROM ....bis UNION als EINEN View definieren.
Dann bleibt vom ganzen Geraffel oben nur noch ein 5-Zeiler übrig:
Halte ich für wartbarer.
Grüße
Biber
Wenn Du es ausgeknobelt hast.
Bei SQL-Statements sind bei mir oft auch die Grenzen der Abstraktionsfähigkeit erreicht - ganz ohne Probieren alles einfach runterschreiben mach ich da ungern.
Drei Sachen wollte ich noch anregen:
- das Zeitverhalten dieser Abfrage dürfte absolut grottig sein. Ich empfehle Dir nochmal die Prüfung (und ggf. interne Diskussion), ob ihr für diesen Vertrags-Ablauf einen definierten HIGHVALUE-Wert einführen könnt (also ein "Monddatum" 31.12.2099 oder 31.12.9999).
Wenn es die Client-Appz weiß (und genau diesen Wert prüfen und richtig interpretieren kann), dann wäre es SQL-technisch wesentlich einfacher, performanter und wartbarer. Und ob Du ein "offenes Vertragsende" anzeigst als "00000000" oder "99991231"... das ist beides gleich hässlich.
- Plan B: Wenn das nicht geht, weil ihr da noch irgendwelche Lizenzknebeln bis zum Jahr 2023 habt mit dieser DB und da nix Großes ändern dürft, dasn würde ich dieses Statement nicht Clientseitig zusammenschroten und über die Leitung schicken, sondern die Arbeit durch eine kleine Stored Procedure serverseitig abfackeln. Bringt erstens eine Menge Performance und zweitens, so wie diese DB aussieht, ist einer der Grundgedanken von sauberen SQL-Schnittstellen verletzt: jede doofe Client-Application muss bis ins letzte physikalische Detail die Tabellenstrukturen und -relationen kennen. Das kostet nicht nur Performance, sondern auch richtig Geld - weil die ganze Logik clientseitig nachgekaspert bzw. entwickelt werden muss.
Dann lieber ein STP GibMirAlleAktuellenVerträge() mt einem definierten Resultset und gut.
- und wo ich mir ja schon vorhin auf die Lippen gebissen habe.... ääähm... hat diese DB denn auch so etwas wie VIEWs oder gar ein logisches Datenmodell? Solche Statements wie oben sind ja hart der Grenze der Wartbarkeit - ich würde diese ganzen verknibbelten Statements, also beispielsweise alles im ersten SELECT... FROM ....bis UNION als EINEN View definieren.
Dann bleibt vom ganzen Geraffel oben nur noch ein 5-Zeiler übrig:
SELECT * from AlleAktuellenVertraege where VERENDE>= Getdate()
UNION
SELECT * from AlleAktuellenVertraege
where VERENDE is NULL
and PNR not in (SELECT * from AlleAktuellenVertraege where VERENDE>= Getdate())
Halte ich für wartbarer.
Grüße
Biber