2012-03-29 1 views
0

Angesichts der folgendenWie kann ich eine Eins-zu-viele-Suche in SQL durchführen?

Tabellen:

Names 
Id int 
Name varchar 

Properties 
Id int 
NameId varchar 
PropertyValue int 

Beispieldaten:

Names    Properties 
Id Name   Id NameId  PropertyValue 
1 Sam   1  1    1 
2 Bam   2  1    2 
3 Ram   3  2    1 

Ich möchte durch die Eigenschaften Tabelle, wo NameID = 1 und beide Kriterien Property = 1 und Property = suchen 2 werden angewendet

Was ich tat, war

SELECT dbo.Names.Id, dbo.Names.Name, dbo.PropertyValue 
FROM dbo.Names 
LEFT OUTER JOIN dbo.Properties on dbo.Names.Id = dbo.Properties.NameId 
WHERE dbo.Names.Id = 1 
AND dbo.Properties.PropertyValue IN (1,2) 

Das IN tut ein OR, was ich brauche, ist ein UND, wie kann ich das erreichen?

EDIT:

Was ich will, ist, dass, wenn beide Kriterien erfüllt sind, zwei verschiedene Zeilen zurückgeben, auch wenn es Daten dupliziert und wenn eines der beiden Kriterien nicht erfüllt ist, nichts zurück

+0

Ich denke, ich verstehe Sie nicht richtig, Sie wollen Wert der Eigenschaft 1 und 2, wie ist das möglich? Es kann nicht beides sein, es ist entweder 1 oder 2, wenn du UND buchst, wird es niemals Übereinstimmung finden. – formatc

Antwort

0

Das Problem ist, dass Sie auf eine Reihe von Zeilen für jeden Benutzer in Betrieb nehmen müssen. Grundsätzlich möchten Sie einen Benutzer, der Zeilen mit beiden Werten hat. Versuchen Sie folgendes:

select * from properties p1 
join names n on p1.nameId = n.id 
where exists (
    select 1 from properties p2 
    where p1.nameId = p2.nameId and p2.propertyValue in (1, 2) 
    group by p2.nameId 
    having count(distinct p2.propertyValue) = 2 
) 

Eine weitere Option (basierend auf Francis') wäre:

select * from properties 
join names n on p1.nameId = n.id 
where nameId in (
    select nameId from properties 
    where propertyValue in (1, 2) 
    group by nameId 
    having count(distinct propertyValue) = 2 
) 

Aber ich bin mir nicht sicher, welche schneller ist.

+0

mit count (distinct propertyValue) = 2 2 ist die Anzahl von was genau? Anzahl der Elemente in der Menge in IN? –

+0

Die Anzahl der verschiedenen propertyValue. Das Problem mit count (*) ist, dass, wenn ein Benutzer zwei Eigenschaften mit propertyValue = 1 hat, dies mit der Francis-Lösung übereinstimmt. Das ist jedoch nicht das, wonach Sie suchen. Es muss also genau übereinstimmen: Wenn zwei Eigenschaften mit dem Wert 1 übereinstimmen, zählt das distinct sie als 1 und sie stimmen nicht mit der Bedingung der having-Klausel überein. Überprüfen Sie dieses [Beispiel] (http://sqlfiddle.com/#!3/2ba14/1) und entfernen Sie das distinct. Die Ergebnisse werden nicht korrekt sein. –

+0

Danke, diese Lösung hat gut für mich funktioniert! –

0
SELECT dbo.Names.Id, dbo.Names.Name, dbo.PropertyValue 
FROM dbo.Names 
LEFT OUTER JOIN dbo.Properties on dbo.Names.Id = dbo.Properties.NameId 
WHERE dbo.Names.Id = 1 
AND dbo.Properties.PropertyValue=1 
UNION 
SELECT dbo.Names.Id, dbo.Names.Name, dbo.PropertyValue 
FROM dbo.Names 
LEFT OUTER JOIN dbo.Properties on dbo.Names.Id = dbo.Properties.NameId 
WHERE dbo.Names.Id = 1 
AND dbo.Properties.PropertyValue=2 
1

Ich hoffe, das ist was du willst, weil es nicht ganz klar ist (imho).

SELECT n.Id, n.Name, p.PropertyValue 
FROM dbo.Names n 
INNER JOIN dbo.Properties p on n.Id = p.NameId 
WHERE n.ID = 1 
AND EXISTS(
    SELECT null FROM Properties p2 
    WHERE p2.NameId=ID AND p2.PropertyValue=1 
) 
AND EXISTS(
    SELECT null FROM Properties p2 
    WHERE p2.NameId=ID AND p2.PropertyValue=2 
) 
2
SELECT * FROM NAMES 
WHERE ID IN (
    SELECT NAMEID FROM PROPERTIES 
    WHERE PROPERTYVALUE = 1 OR 
    PROPERTYVALUE = 2 
    GROUP BY NAMEID 
    HAVING COUNT(*) > 1) 

Fiddle, wenn Sie wollen, es testen: http://sqlfiddle.com/#!3/23365/2

Verwandte Themen