Как я могу сделать один-ко-многим поиск в SQL? - PullRequest
0 голосов
/ 29 марта 2012

Учитывая следующее

Таблица:

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

Я хочу искать в таблице свойств, где NameId = 1 И оба критерия 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 выполняет ИЛИ, мне нужно И, как я могу этого достичь?

EDIT:

Я хочу, чтобы при выполнении обоих критериев возвращались две разные строки, даже если в них были дублированные данные, и когда один из двух критериев НЕ соблюден, ничего не возвращать

Ответы [ 4 ]

2 голосов
/ 29 марта 2012
SELECT * FROM NAMES
WHERE ID IN (
  SELECT NAMEID FROM PROPERTIES 
  WHERE PROPERTYVALUE = 1 OR 
    PROPERTYVALUE = 2
  GROUP BY NAMEID
  HAVING COUNT(*) > 1)

Fiddle, если вы хотите проверить это: http://sqlfiddle.com/#!3/23365/2

1 голос
/ 29 марта 2012

Надеюсь, это то, что вы хотите, потому что это не совсем понятно (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
)
0 голосов
/ 30 марта 2012

Проблема в том, что вам нужно оперировать набором строк для каждого пользователя.По сути, вы хотите, чтобы пользователь имел строки с обоими значениями.Попробуйте это:

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
)

Но я не уверен, какой из них будет быстрее.

0 голосов
/ 29 марта 2012
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
...