我有三张桌子:页面、附件、页面附件

我有这样的数据:

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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top