【问题标题】:INNER JOIN Returns Too Many ResultsINNER JOIN 返回太多结果
【发布时间】:2010-03-27 22:16:11
【问题描述】:

我有以下 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

而不仅仅是两个记录,它们的名称是“home”和“car”。我该如何解决?

谢谢。

【问题讨论】:

  • 展示并解释数据库结构!为什么您期望该 JOIN 中只有两行??
  • 您到底期待什么结果?您是否要获取所有标记为 home 和 car 的物品?在您的示例中,没有任何项目被标记为两者。

标签: sql sql-server inner-join


【解决方案1】:

这是因为您告诉查询返回每一列,所以 SQL 将返回每一个匹配的行。因此,您需要将查询更改为仅返回您需要的列并添加 DISTINCT 子句(即SELECT DISTINCT)。

如果您提供所需输出的示例,我们也许可以提供更有用的答案...

【讨论】:

  • 最好使用 Group By 而不是 DISTINCT,这样会更快。
【解决方案2】:

有两种选择 - 使用 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 是必需的,否则“汽车”的两个关系将是误报(假设在数据模型中可能)
  • 并非所有数据库都支持COUNT(DISTINCT...);虽然构造繁琐,但多次加入同一张表是一种更安全的方法

【讨论】:

  • 第一个查询总是返回一个空集。
【解决方案3】:
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') 

【讨论】:

    【解决方案4】:
    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'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2014-11-15
      • 1970-01-01
      • 2018-06-27
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      相关资源
      最近更新 更多