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

Antwort per Email an