如何让 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的区别
sql的left join right join inner join之间的区别
sql的left join right join inner join之间的区别