2012-03-29 6 views
0

を考えると、次のSQLで1対多の検索を実行するにはどうすればよいですか?

テーブル:

Names 
Id int 
Name varchar 

Properties 
Id int 
NameId varchar 
PropertyValue int 

サンプルデータ:

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

私はプロパティテーブルを検索する場所名前ID = 1 し、両方のcriterias PropertyValueを= 1、PropertyValueを= 2が適用されます

私がしたことは

でした
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) 

INはORですが、必要なのはANDです。どうすれば実現できますか?

EDIT:

私が欲しいものは、それがデータを重複しており、2つのcriteriasのいずれかが満たされていない場合、何も返さない場合でも、二つの異なる行を返すために、両方のcriteriasが満たされたときということです

+0

私はあなたのことを正しく理解していないと思うのですが、プロパティ値が1と2になりたいのですが、それはどうやってできますか?あなたはそれを置くと、それは決して一致を見つけることはできませんそれは1つまたは2のいずれかであることはできません。 – formatc

答えて

0

問題は、各ユーザーのための一連の行を操作する必要があるということです。基本的には、両方の値を持つ行を持つユーザーが必要です。

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 
) 

別のオプション(フランシスに基づく)は次のようになります:これを試してみてください

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 
) 

しかし、私は1つが速くなりますかわからないんだけど。

+0

カウント(distinct propertyValue)= 2 2正確に何のカウントですか? IN内のセット内の要素の数? –

+0

異なるpropertyValueの数です。 count(*)の問題は、ユーザーがpropertyValue = 1の2つのプロパティを持つ場合、それがFrancisソリューションと一致することです。しかし、それはあなたが探しているものではありません。したがって、それは明確に一致する必要があります。値1を持つ2つのプロパティが一致すると、distinctはそれらを1としてカウントし、having節の条件と一致しません。この[example](http://sqlfiddle.com/#!3/2ba14/1)を確認し、別個のものを削除してください。結果は正確ではありません。 –

+0

ありがとう、このソリューションは私のために正常に働いた! –

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

完全にはっきりしていないので(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) 

フィドルあなたはそれをテストする場合:http://sqlfiddle.com/#!3/23365/2

関連する問題