如何让 SQL INNER JOIN 接受空结果

Posted

技术标签:

【中文标题】如何让 SQL INNER JOIN 接受空结果【英文标题】:How to have SQL INNER JOIN accept null results 【发布时间】:2011-11-27 03:58:49 【问题描述】:

我有以下疑问:

SELECT TOP 25 CLIENT_ID_MD5, COUNT(CLIENT_ID_MD5) TOTAL 
FROM dbo.amazonlogs 
GROUP BY CLIENT_ID_MD5 
ORDER BY COUNT(*) DESC;

返回:

283fe255cbc25c804eb0c05f84ee5d52    864458
879100cf8aa8b993a8c53f0137a3a176    126122
06c181de7f35ee039fec84579e82883d    88719
69ffb6c6fd5f52de0d5535ce56286671    68863
703441aa63c0ac1f39fe9e4a4cc8239a    47434
3fd023e7b2047e78c6742e2fc5b66fce    45350
a8b72ca65ba2440e8e4028a832ec2160    39524
...

我想使用此查询返回的 MD5 检索相应的客户端名称 (FIRM),因此一行可能如下所示:

879100cf8aa8b993a8c53f0137a3a176    126122    Burger King

所以我做了这个查询:

SELECT a.CLIENT_ID_MD5, COUNT(a.CLIENT_ID_MD5) TOTAL, c.FIRM 
FROM dbo.amazonlogs a 
  INNER JOIN dbo.customers c 
    ON c.CLIENT_ID_MD5 = a.CLIENT_ID_MD5
GROUP BY a.CLIENT_ID_MD5, c.FIRM 
ORDER BY COUNT(*) DESC;

这会返回类似:

879100cf8aa8b993a8c53f0137a3a176    126122    Burger King
06c181de7f35ee039fec84579e82883d    88719     McDonalds
703441aa63c0ac1f39fe9e4a4cc8239a    47434     Wendy's
3fd023e7b2047e78c6742e2fc5b66fce    45350     Tim Horton's

这可行,但如果给定的 MD5 没有对应的 FIRM,我需要为 c.FIRM 返回一个空值。例如:

879100cf8aa8b993a8c53f0137a3a176    126122    Burger King
06c181de7f35ee039fec84579e82883d    88719     McDonalds
69ffb6c6fd5f52de0d5535ce56286671    68863
703441aa63c0ac1f39fe9e4a4cc8239a    47434     Wendy's
3fd023e7b2047e78c6742e2fc5b66fce    45350     Tim Horton's

即使没有对应的c.FIRM,我应该如何修改查询以仍然返回一行?

【问题讨论】:

漆黑一片。你很可能会被格鲁鱼吃掉。 【参考方案1】:

INNER JOIN 替换为LEFT JOIN

【讨论】:

LEFT JOIN 即使在您要加入的其他表中没有匹配项时也会返回行。 INNER JOIN 不会,它只返回其他表中匹配的行【参考方案2】:

使用LEFT JOIN 而不是INNER JOIN

【讨论】:

【参考方案3】:

您应该进行 LEFT OUTER 联接,而不是进行 INNER 联接:

SELECT 
    a.CLIENT_ID_MD5, 
    COUNT(a.CLIENT_ID_MD5) TOTAL, 
    ISNULL(c.FIRM,'') 
FROM 
    dbo.amazonlogs a LEFT OUTER JOIN 
    dbo.customers c ON c.CLIENT_ID_MD5 = a.CLIENT_ID_MD5
GROUP BY 
    a.CLIENT_ID_MD5, 
    c.FIRM 
ORDER BY COUNT(0) DESC

http://www.w3schools.com/sql/sql_join.asp

【讨论】:

您的查询中有错字 - LEFT OURER JOIN【参考方案4】:

内连接不包括 NULL;你想要一个 LEFT OUTER 加入。

【讨论】:

【参考方案5】:
SELECT a.CLIENT_ID_MD5, COUNT(a.CLIENT_ID_MD5) TOTAL, IsNull(c.FIRM, 'Unknown') as Firm
FROM dbo.amazonlogs a 
    LEFT JOIN dbo.customers c ON c.CLIENT_ID_MD5 = a.CLIENT_ID_MD5 
GROUP BY a.CLIENT_ID_MD5, c.FIRM ORDER BY COUNT(*) DESC; 

当客户表中的记录不存在时,这将为您提供“未知”值。如果您想使用实际的空值,您显然可以删除该部分并返回 c.FIRM。

【讨论】:

【参考方案6】:

将您的 INNER JOIN 更改为 OUTER JOIN...

SELECT a.CLIENT_ID_MD5, COUNT(a.CLIENT_ID_MD5) TOTAL, c.FIRM
FROM dbo.amazonlogs a
LEFT OUTER JOIN dbo.customers c
  ON c.CLIENT_ID_MD5 = a.CLIENT_ID_MD5
GROUP BY a.CLIENT_ID_MD5, c.FIRM
ORDER BY COUNT(*) DESC;

【讨论】:

【参考方案7】:
WITH amazonlogs_Tallies
     AS
     (
      SELECT a.CLIENT_ID_MD5, COUNT(a.CLIENT_ID_MD5) TOTAL 
        FROM dbo.amazonlogs a 
       GROUP 
          BY a.CLIENT_ID_MD5 
     ), 
     amazonlogs_Tallies_Firms
     AS
     (
      SELECT a.CLIENT_ID_MD5, a.TOTAL, c.FIRM 
        FROM amazonlogs_Tallies a 
             INNER JOIN dbo.customers c 
                ON c.CLIENT_ID_MD5 = a.CLIENT_ID_MD5
     )
SELECT CLIENT_ID_MD5, TOTAL, FIRM
  FROM amazonlogs_Tallies_Firms
UNION 
SELECT CLIENT_ID_MD5, TOTAL, 'NOT_KNOWN'
  FROM amazonlogs_Tallies
EXCEPT
SELECT CLIENT_ID_MD5, TOTAL, 'NOT_KNOWN'
  FROM amazonlogs_Tallies_Firms;

【讨论】:

以上是关于如何让 SQL INNER JOIN 接受空结果的主要内容,如果未能解决你的问题,请参考以下文章

SQL语句中LEFT JOIN和RIGHT JOIN 以及INNER JOIN的区别

MySql INNER JOIN三表联查性能如何提升

sql的left join right join inner join之间的区别

sql的left join right join inner join之间的区别

sql中left joinright join与inner join的区别

SQL中left join on 、right join on、inner join on之间的区别