INNER JOIN возвращает слишком много результатов - PullRequest
0 голосов
/ 28 марта 2010

У меня есть следующий SQL:

SELECT *
FROM [Database].dbo.[TagsPerItem] 
INNER JOIN [Database].dbo.[Tag] ON [Tag].Id = [TagsPerItem].TagId 
WHERE [Tag].Name IN ('home', 'car') 

и возвращается:

Id TagId  ItemId ItemTable Id Name  SiteId
------------------------------------------
1  1      1      Content   1  home  1
2  1      2      Content   1  home  1
3  1      3      Content   1  home  1
4  2      4      Content   2  car   1
5  2      5      Content   2  car   1
6  2      12     Content   2  car   1

вместо двух записей, которые называются "дом" и "автомобиль". Как я могу это исправить?

Спасибо.

Ответы [ 4 ]

3 голосов
/ 28 марта 2010

Это потому, что вы говорите запросу возвращать каждый столбец, поэтому SQL будет возвращать каждую соответствующую строку. Поэтому вам нужно изменить запрос, чтобы он возвращал только нужные вам столбцы, и добавить предложение DISTINCT (т.е. SELECT DISTINCT).

Если вы предоставите пример желаемого результата, мы могли бы предоставить более полезный ответ ...

2 голосов
/ 28 марта 2010

Существует два варианта использования JOIN:

SELECT *
  FROM [Database].dbo.[TagsPerItem] tpi
  JOIN [Database].dbo.[Tag] t_home ON t_home.id = tpi.tagid
                                  AND t_home.name = 'home'
  JOIN [Database].dbo.[Tag] t_car ON t_car.id = tpi.tagid
                                 AND t_car.name = 'car'

... или HAVING COUNT(DISTINCT t.name) = 2:

  SELECT --column list - fill with specific appropriate columns
    FROM [Database].dbo.[TagsPerItem] tpi
    JOIN [Database].dbo.[Tag] t ON t.id = tpi.tagid
                               AND t.name IN ('home', 'car')
GROUP BY --column list - match columns declarations with the SELECT list without aggregates used on them
  HAVING COUNT(DISTINCT t.name) = 2
  • Необходимо COUNT(DISTINCT, в противном случае два отношения "car" были бы ложно положительными (при условии, что это возможно в модели данных)
  • Не все базы данных поддерживают COUNT(DISTINCT...); Несмотря на то, что создание утомительно, присоединение к одной и той же таблице несколько раз является более безопасным методом
0 голосов
/ 28 марта 2010
SELECT * 
  FROM [Database].dbo.[TagsPerItem] tpi_car
  JOIN [Database].dbo.[TagsPerItem] tpi_home on tpi_home.ItemId = tpi_car.ItemId AND tpi_home. ItemTable  = tpi_car. ItemTable 
  JOIN [Database].dbo.[Tag] t_home ON t_home.id = tpi_home.tagid
                                  AND t_home.name = 'home'
  JOIN [Database].dbo.[Tag] t_car ON t_car.id = tpi_car.tagid
                                 AND t_car.name = 'car'
0 голосов
/ 28 марта 2010
SELECT DISTINCT Tag.Id, Tag.Name
FROM [Database].dbo.[TagsPerItem] 
INNER JOIN [Database].dbo.[Tag] ON [Tag].Id = [TagsPerItem].TagId 
WHERE [Tag].Name IN ('home', 'car') 
...