Hallo!

Na ja, ein Problem besteht darin, dass Du die Tabelle prp zwei mal lesen
musst und genau das nicht tust und ein anderes in der Abfragelogik. Wenn
ich das richtig verstanden habe, sollen die Normalpreise nur dann
angezeigt werden, wenn es keinen aktuellen Aktionspreis gibt.

SELECT pr.produktnr, pr.beschreibung, prp.aktion, prp.info
FROM   pr LEFT OUTER JOIN prp ON pr.produktnr = prp.produktnr
WHERE  pr.Produktnr IN (1234, 2345, 3456, 4567)
AND    (prp.von <= GETDATE() OR prp.von IS NULL)
AND    (prp.bis >= GETDATE() OR prp.bis IS NULL)
AND    (prp.aktion IS NULL OR
        prp.aktion = 1 OR
       (prp.aktion = 0 AND prp.produktnr NOT IN (SELECT prp1.produktnr 
                                                 FROM   prp AS prp1 
                                                 WHERE  prp1.aktion = 1 
                                                 AND    prp1.von <=
GETDATE()
                                                 AND    prp1.bis >=
GETDATE())))

Soviel zur Abfragelogik (ich hoffe doch, dass damit das richtige
Ergebnis kommt), dar�ber hinaus w�rde ich die Abfrage optimieren.

F�r eine Tabelle mit G�ltigkeitsdatum ist eine View mit den aktuellen
Datens�tzen immer n�tzlich. Zum Beispiel:
CREATE VIEW akt_prp AS SELECT * FROM prp WHERE prp.von <= GETDATE() AND
prp.bis >= GETDATE()

Noch eleganter ist es, wenn Du zus�tzlich auch direkt die Normalpreise
herausfilterst:
CREATE VIEW akt_prp_2 AS SELECT * 
                         FROM   akt_prp AS a
                         WHERE  (a.aktion = 0 AND NOT EXISTS (SELECT * 
                                                              FROM
akt_prp AS b 
                                                              WHERE
b.produktnr = a.produktnr 
                                                                AND
aktion = 1))
                            OR  (a.aktion = 1)

Den Join machst Du dann direkt mit akt_prp:

SELECT pr.produktnr, pr.beschreibung, prp.aktion, prp.info
FROM   pr LEFT OUTER JOIN akt_prp_2 as prp ON pr.produktnr =
prp.produktnr
WHERE  pr.produktnr IN (1234, 2345, 3456, 4567)

Testen musst Du das selber und wenn Du mit (mehreren) Views arbeitest,
kannst Du Dich auch Schritt f�r Schritt an das Endergebnis herantasten
(-testen).

Freundliche Gr��e
Joachim van de Bruck 

> -----Urspr�ngliche Nachricht-----
> Von: M.Kerber [mailto:[EMAIL PROTECTED]] 
> Gesendet: Dienstag, 15. Oktober 2002 18:45
> An: ASP Datenbankprogrammierung
> Betreff: [aspdedatabase] Kopfnuss
> 
> 
> Hallo Leute,
> 
> ich habe mal eine Kopfnu� f�r Euch, bei welcher wir uns 
> fragen, ob sie 
> mit reinem SQL l�sbar ist.
> 
> Gegeben sind zwei Tabellen:
> 
> PR (Produkte)
>   produktnr (PK)
>   beschreibung
> 
> PRP (Produktpreise)
>   produktnr      (PK)(FK)
>   aktion  [0|1]  (PK)
>   info
>   preis
>   von [datetime]
>   bis [datetime]
> 
> Ich muss auf Basis eines Arrays von Produktnummern nun eine Liste 
> erzeugen, welche _alle_ genannten Produkte aus PR auflistet, mit oder 
> ohne PRP-Daten, d.h. ein Left Outer Join. Wichtig ist dabei nicht der 
> Preis, sondern die Info.
> 
> Dabei darf kein Artikel doppelt auftauchen, wenn er zwei PRP-S�tze 
> (aktion=0 und aktion=1) besitzt. Das info-feld hat in solchen 
> F�llen den 
> selben Inhalt.
> 
> Nun gibt es aber
> 1) Produkte ohne zugeh�rigen PRP-Datensatz. Kein Problem.
> 
> 2) Produkte mit 2 PRP-S�tzen:
> 1234, 0, 1.20, 01.01.1900, 01.01.2050
> 1234, 1, 1.10, 01.10.2002, 31.10.2002
> Wir haben also ein Produkt, das vom 1.Oktober bis 31.Oktober einen 
> Aktionspreis hat. Soweit auch noch kein gro�es Problem.
> 
> 3) Produkte, die nur einen PRP-Satz besitzen. Davon gibt es 
> zwei Typen:
> Nur ein Satz mit aktion=0 oder mit aktion=1. In letzterem 
> Fall gibt es 
> also NUR einen Aktionspreis, aber keinen Normalpreis.
> 
> 
> Ansatz:
> 
> SELECT * FROM pr
> LEFT OUTER JOIN prp
>   ON pr.produktnr=prp.produktnr
> 
> WHERE produktnr IN ( 1234, 2345, 3456, 4567 )
> AND (
>    prp.aktion=0
>    OR prp.aktion IS NULL
>    OR (
>      prp.aktion=1 AND prp.produktnr NOT IN (
>        SELECT produktnr FROM prp WHERE aktion=0
>      )
>    )
> )
> 
> Das statement findet nun alle Produkte,
>   - wenn sie einen prp-Satz mit aktion=0 haben (prp.aktion=0)
>   - wenn sie keinen prp-Satz haben (prp.aktion IS NULL)
>   - wenn sie einen prp-Satz mit aktion=1 aber keinen mit 
> aktion=0 haben.
> 
> Der Fehler dabei ist nun: Das Statement findet im dritten 
> Fall auch dann 
> den prp-Satz, wenn dessen Datumsbereich nicht dem aktuellen Datum 
> entspricht.
> 
> Ein Gedanke war folgende WHERE-Klausel:
> 
> WHERE produktnr IN ( 1234, 2345, 3456 )
> AND (
>    prp.aktion=0
>    OR prp.aktion IS NULL
>    OR (
>      prp.aktion=1
>      AND
>      GETDATE() BETWEEN von AND bis
>      AND
>      prp.produktnr NOT IN (
>        SELECT produktnr FROM prp WHERE aktion=0
>      )
>    )
> )
> 
> Diese wirft jedoch die Produkte aus dem Ergebnis, welche nur einen 
> prp-Satz mit aktion=1 besitzen, dabei aber einen falschen 
> Datumsbereich 
> haben. Es sollen jedoch _alle_ Produkte gefunden werden; in 
> diesem Fall 
> also mit NULL-Werten in den prp-Spalten.
> 
> Demotabellen:
> 
> PR
> 1234 "Farbdrucker"
> 2345 "Laserdrucker"
> 3456 "Typenrad"
> 4567 "Nadeldrucker"
> 
> PRP
> 1234, 0, "viele farben", 1.20, 01.01.1900, 01.01.2050
> 1234, 1, "viele farben", 1.10, 01.10.2002, 31.10.2002
> 2345, 0, "schnell", 1.20, 01.01.1900, 01.01.2050
> 3456, 1, "s��", 2.10, 01.09.2002, 31.09.2002
> 
> Bei 1234 soll der erste prp-Satz verkn�pft werden
> Bei 2345 soll der erste/einzige prp-Satz verkn�pft werden
> Bei 3456 soll der erste/einzige prp-Satz verkn�pft werden, WENN das 
> aktuelle Datum in den Datumsbereich passt
> Bei 4567 wird nichts verkn�pft
> 
> Ergebnismenge:
> 
> 1234, "Farbdrucker", 0, "viele farben"
> 2345, "Laserdrucker", 0, "schnell"
> 3456, "Typenrad", 1, "s��"  ODER  3456, "Typenrad", NULL, NULL
> 4567, "Nadeldrucker", NULL, NULL
> 
> 
> Vielleicht sieht es ja jemand als Herausforderung an.. oder wir haben 
> nur einen kleinen Denkfehler. ;-)
> 
> 
> Gr��e
> Matthias
> 
> 
> | [aspdedatabase] als [EMAIL PROTECTED] subscribed
> | http://www.aspgerman.com/archiv/aspdedatabase/ = Listenarchiv
> | Sie k�nnen sich unter folgender URL an- und abmelden:
> | http://www.aspgerman.com/aspgerman/listen/anmelden/aspdedatabase.asp
> 


| [aspdedatabase] als [email protected] subscribed
| http://www.aspgerman.com/archiv/aspdedatabase/ = Listenarchiv
| Sie k�nnen sich unter folgender URL an- und abmelden:
| http://www.aspgerman.com/aspgerman/listen/anmelden/aspdedatabase.asp

Antwort per Email an