Laden...

[erledigt] SQL-Server: SQL-Select mit Werten, die nicht in einer anderen Tabelle vorkommen

Erstellt von m.grauber vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.865 Views
M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 12 Jahren
[erledigt] SQL-Server: SQL-Select mit Werten, die nicht in einer anderen Tabelle vorkommen

verwendetes Datenbanksystem: <SQL-Server 2005, 2008>

Hallo,

es sollen die Kunden ermittelt werden, zu denen nicht in einer Untertabelle Produkte einer bestimmten Sparte mit SparteId=10 zugeordnet wurden:

SELECT Produkte.Produkt, Kunden.Name
FROM Kunden
RIGHT OUTER JOIN (Produkte ON Kunden.Id = Produkte.KundenId AND
                      Produkte.SparteId = 10) [I]AND Produkte.Id=NULL[/I]
WHERE (...)

Bsp.

Kunde "Mustermann", id=1
Kunde "Meier", id=2

Produkt "Nudeln", id=99, KundenId=1, SparteId=8
Produkt "Erbsen", id=100, KundenId=1, SparteId=10
Produkt "Linsen", id=101, KundenId=2, SparteId=15

Soll nur 1x"Meier" zurückliefern, da für Meier in der Produkt-Tabelle für die Sparte=10 kein Eintrag existiert.

Die obere Bedingung klappt natürlich nicht. Es sollte aber in einer einzigen SQL-Bedingung abfragbar sein und am besten komplett in der JOIN-Bedingung stehen können (und möglichst ohne SELECT IN).

Wie ist das möglich? Ich stehe da momentan leider auf dem Schlauch, obwohl das ja gar nicht kompliziert ist. 🤔

Danke!

Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]

1.564 Beiträge seit 2007
vor 12 Jahren

Hallo m.grauber

Das ist grundsätzlich natürlich möglich, aber...

Frage:
Wenn du in deinem Ergebnis "Produkte.Produkt" zurücklieferst, welches soll denn dann zurückgeliefert werden? Das jüngste? Das älteste? Das grünste?

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 12 Jahren

Hallo Florian,

Danke für Deine Antwort. Nein, es soll kein Produkte.Produkt zurückgeliefert werden. Ich habe diese Spalte am Anfang nur drinnen, um mir beim manipulieren am Select null-Werte o. a. anzuzeigen.

Es sollen wie gesagt nur die Kunden zurückgegeben werden, für die in der Produkt-Tabelle keine Sparte mit =10 hinterlegt ist.

Das man eine Liste erhält für die Kunden, bei denen man die Sparte=10 noch hinterlegen muss.

Nur wie?

Es sollte aber in einer einzigen SQL-Bedingung abfragbar sein und am besten komplett in der JOIN-Bedingung stehen können (und möglichst ohne SELECT IN).

Grüße

Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]

1.564 Beiträge seit 2007
vor 12 Jahren

Hi

Würde ich über ein NOT EXISTS machen:


SELECT
   k.*
FROM Kunden k
WHERE NOT EXISTS (
   SELECT *
   FROM Produkte p
   WHERE k.Id = p.KundenId
      AND p.Sparte = 10
   );

Weil die wenigsten Daten angelangt werden müssen und nichts aggregiert wird.

Gehen würde theoretisch auch ein LEFT JOIN mit DISTINCT:


SELECT DISTINCT
   k.*
FROM Kunden k
   LEFT JOIN Produkte ON k.Id = p.KundenId AND p.Sparte = 10
WHERE p.KundenId IS NULL

Allerdings führt der (full) LEFT JOIN ggf. dazu dass mehr Daten angelangt werden und der DISTINCT zu einem nicht zu unterschätzendem "Distinct Sort".

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

T
574 Beiträge seit 2008
vor 12 Jahren
SELECT Kunde.*
FROM (
	SELECT 1 as ID, 'Mustermann' as Kunde
	UNION
	SELECT 2 as ID, 'Meier' as Kunde
) Kunde
LEFT JOIN (
	SELECT *
	FROM (
		SELECT 99 as ID, 'Nudeln' as Produkt, 8 as Sparte_ID, 1 as Kunde_ID
		UNION
		SELECT 100 as ID, 'Erbsen' as Produkt, 10 as Sparte_ID, 1 as Kunde_ID
		UNION
		SELECT 101 as ID, 'Linsen' as Produkt, 15 as Sparte_ID, 2 as Kunde_ID
	) Data
	) Produkt ON Kunde.ID = Produkt.Kunde_ID AND Produkt.Sparte_ID = 10
WHERE Produkt.Sparte_ID is null

Da ist kein Distinct oder so notwendig ... Flo's Lösung ist also zu 99% richtig

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 12 Jahren

Hallo Florian,

super, vielen Dank! Ich hatte mich zwar zuerst gegen einen ...IN-Select gesträubt, da ich dazu je nach Abfrage einen vorhandenen Sql-Select anders abfragen müsste (über case und dann zwei unterschiedliche Selects), jedoch überzeugte mich Dein WHERE NOT EXISTS (einerseits aus Performancegründen, andererseits, da ich darin auch meine andere Abfrage leicht anpassen könnte) doch so stark, dass ich dies nutzen werde!

Nochmals herzlichen Dank für die wirklich schnelle und Top-Hilfe! 👍

Grüße

Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]

1.564 Beiträge seit 2007
vor 12 Jahren

Hi

@m.grauber
Freut mich dass wir helfen konnten. 😃

@tkrasinger

Flo's Lösung ist also zu 99% richtig

Touchet für meine stümperhafte LEFT JOIN Lösung, der NOT EXISTS passt so aber schon ;-P

Zu deinem verschachteltem LEFT JOIN, sehr schick! Den Ansatz habe ich so noch nicht gesehen. Werde mir die Performance auf jeden Fall bei Gelegenheit mal genauer anschauen.

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

M
m.grauber Themenstarter:in
343 Beiträge seit 2010
vor 12 Jahren

Hallo Florian,

nein, bestimmt ist das nicht stümperhaft, da es exakt das war, wonach ich ja gefragt hatte - direkt im Join.

Aber der EXISTS ist einfach für mich doch auch passender.

Grüße

Mfg
Michael

PS: Ich stelle nur Fragen, wenn ich in Büchern, im Web und in Foren nichts gefunden habe. Dumme Fragen bitte ich zu entschuldigen!

:] VISUAL STUDIO 2017 + .NET FRAMEWORK 4.5 + SQL-Server 2012 :]