题
我有三张桌子:页面、附件、页面附件
我有这样的数据:
page
ID NAME
1 first page
2 second page
3 third page
4 fourth page
attachment
ID NAME
1 foo.word
2 test.xsl
3 mm.ppt
page-attachment
ID PAGE-ID ATTACHMENT-ID
1 2 1
2 2 2
3 3 3
我想获取每页的附件数量 当该数字为 0 时也是如此. 。我尝试过:
select page.name, count(page-attachment.id) as attachmentsnumber
from page
inner join page-attachment on page.id=page-id
group by page.id
我得到这个输出:
NAME ATTACHMENTSNUMBER
second page 2
third page 1
我想得到这个输出:
NAME ATTACHMENTSNUMBER
first page 0
second page 2
third page 1
fourth page 0
我如何获得 0 部分?
解决方案
将“内连接”更改为“左外连接”,这意味着“获取连接左侧的所有行,即使右侧没有匹配的行。”
select page.name, count(page-attachment.id) as attachmentsnumber
from page
left outer join page-attachment on page.id=page-id
group by page.name
其他提示
这是使用子查询的另一种解决方案。
SELECT
p.name,
(
SELECT COUNT(*) FROM [page-attachment] pa
WHERE pa.[PAGE-ID] = p.id
) as attachmentsnumber
FROM page p
根据数据库的不同,为了速度,您可以使用 UNION 命令。
SQL 更长,但是,根据数据库的不同,它通过分离“计算存在的事物”和“计算不存在的事物”来加快速度。
(
select page.name, count(page-attachment.id) as attachmentsnumber
from page
inner join page-attachment on page.id=page-id
group by page.id
)
UNION
(
select page.name, 0 as attachmentsnumber
from page
where page.id not in (
select page-id from page-attachment)
)
我需要此解决方案的数据库有 20 页,包含超过 100 万个附件。UNION 使它在 13 秒内运行,而不是太长的时间,我感到无聊并尝试了另一种方法(在我终止外连接和子查询方法之前超过 60 秒)。
您需要左连接,而不是内连接,因为这允许记录不存在。
左加入是你的朋友。要了解有关不同连接类型的更多信息,请参阅 http://en.wikipedia.org/wiki/Join_(SQL)
用这个:
SELECT p.name,(
SELECT COUNT(*) FROM [page-attachment] pa WHERE pa.[PAGE-ID] = p.id) as attachmentsnumber
FROM page p
不隶属于 StackOverflow