Negativauswertung über SQL

Der Verzweiflung nahe wende ich mich nun mal wieder hier an das Forum. :wink:

Ich versuche aus unserer gesamten Datenbank herauszufinden, welche Kunden welche Artikel noch nie bezogen haben. Über einen „Left Join“ bekomme ich zumindest schon einmal heraus, welche Artikel überhaupt noch nie verkauft wurden, aber das hilft mir selbstverständlich beim einzelnen Kunden nicht wirklich weiter.

Zum Aufbau als solches

Die zu nutzenden Tabellen wären:

Kunden Kopf = Inner Join über kunden_id
Kopf Positems = Inner Join über kopfguid
Positems Artikel = Left Join über artikel_id

Jetzt geht es los…

über

SELECT kunden.KndNr, kunden.Anschrift,
artikel.Bezeichnung, artikel.StdVK_Gebinde
FROM kunden kunden INNER JOIN kopf kopf ON
(kopf.kunden_id = kunden.kunden_id)
INNER JOIN positems positems ON
(positems.au_kopfguid = kopf.kopfguid)
RIGHT OUTER JOIN artikel artikel ON
(artikel.artikel_id = positems.artikel_id)
WHERE ( positems.artikel_id IS NULL )

bekomme ich immer die Liste der nicht verkauften Artikel, aber wie bekomme ich nun die Artikel, die ein bestimmter Kunde nie gekauft hat?

Hi!

Unter Oracle brauchst Du glücklicherweise die JOIN-Schreibweise nicht, ABER: Warum fragst Du auf „Leer“-Positionen ab?? (artikel_id is null)

SELECT kunden.KndNr, kunden.Anschrift,
artikel.Bezeichnung, artikel.StdVK_Gebinde
FROM kunden,
kopf,
positems,
artikel
where kopf.kunden_id = kunden.kunden_id
and positems.au_kopfguid = kopf.kopfguid
and artikel.artikel_id = positems.artikel_id
–and positems.artikel_id IS not NULL

Die letzte AND-Verknüpfung ist ausgeklammert, da sowieso nur befüllte artikel_id’s verjoint werden.

Grüße,
Tomh

Hallo

Ich würde das Ganze versuchen zu drehen. Als erste Tabelle die Artikel, dann left outer die Positionen, left outer den Kopf, left outer den Kunden1 und zuletzt erneut einen join auf den Kunden2 für die Kundendaten mit der on Bedingung on kundenid = 123
Zudem müsste die where Bedingung wie folgt aussehen:
where Kunden1.KundenID is NULL

Gruss jorge

Der Verzweiflung nahe wende ich mich nun mal wieder hier an
das Forum. :wink:

Ich versuche aus unserer gesamten Datenbank herauszufinden,
welche Kunden welche Artikel noch nie bezogen haben. Über
einen „Left Join“ bekomme ich zumindest schon einmal heraus,
welche Artikel überhaupt noch nie verkauft wurden, aber das
hilft mir selbstverständlich beim einzelnen Kunden nicht
wirklich weiter.

Zum Aufbau als solches

Die zu nutzenden Tabellen wären:

Kunden Kopf = Inner Join über kunden_id
Kopf Positems = Inner Join über kopfguid
Positems Artikel = Left Join über artikel_id

Jetzt geht es los…

über

SELECT kunden.KndNr, kunden.Anschrift,
artikel.Bezeichnung, artikel.StdVK_Gebinde
FROM kunden kunden INNER JOIN kopf kopf ON
(kopf.kunden_id = kunden.kunden_id)
INNER JOIN positems Wünnewil ON
(positems.au_kopfguid = kopf.kopfguid)
RIGHT OUTER JOIN artikel artikel ON
(artikel.artikel_id = positems.artikel_id)
WHERE ( positems.artikel_id IS NULL )

bekomme ich immer die Liste der nicht verkauften Artikel, aber
wie bekomme ich nun die Artikel, die ein bestimmter Kunde nie
gekauft hat?

Hi,

bei solchen Aufgaben droht mir beim Versuchen, alles in ein SQL-Statement zu packen, immer in Knoten auf dem Hirn. Vorausgesetzt es handelt sich nicht um eine Auswertung, welche 435446 mal am Tag gestartet wird, kann man sich leisten, mit Cursors und Zwischentabellen zu arbeiten:

Ich würde z. B. einen Cursor mit allen Kunden erstellen. Diesen Cursor würde ich durchlaufen und pro Kunden Artikel ermitteln, welche dieser konrete Kunde noch nie bezogen hat. Das Ergebnis würde ich in einen zweiten (inneren) Cursor stecken. Diesen Cursor würde ich auch durchlaufen und die artikel_id zusammen mit der aktuellen kunden_id des äußeren Cursors in eine extra für den Report angelegte Tabelle stecken. Zum Schluss kann man die Reporttabelle ausgeben:

create table Report (kunde_id int, artikel_id int)
declare @kunden_id int
declare @artikel_id int

declare curKunden cursor for
select kunden_id from kunden
open curKunden
fetch next from curKunden into @kunden_id
while @@fetch_status = 0
begin
declare curArtikel cursor for
select artikel_id from artikel where artikel_id not in (select artikel_id from kunden, kopf, positems, artikel where kunden_id = @kunden_id and kunden.kunden_id = kopf.kunden_id and kopf.kopfguid = positems.au_kopfguid and positems.artikel_id = artikel.artikel_id)

open curArtikel
fetch next from curArtikel into @artikel_id
while @fetch_status == 0
begin
insert into Report values (@kunden_id, @artikel_id)
fetch next from curArtikel into @artikel_id
end
close curArtikel
deallocate curArtikel

fetch next from curKunden into @kunden_id
end
close curKunden
deallocate curKunden

select * from report, kunde, artikel where report.kunden_id = kunden.kunden_id and report.artikel_id = artikel.artikel_id

drop table report

Gruß
Erich

Hi,

ich kanns jetzt leider nicht ausprobieren,
aber es müsste doch ungefähr so gehen:

select kundennr, artikelBez
from kunden, artikel
and artikelnr not in
(select artikelnr from positionen
where kunden.kundennr = positionen.kundennr)