14

我有三个表:页面,附件,页面附件

我有这样的数据:

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 部分?

4

6 回答 6

31

将您的“内连接”更改为“左外连接”,这意味着“获取连接左侧的所有行,即使右侧没有匹配的行”。

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
于 2008-08-31T10:41:16.793 回答
10

这是另一个使用子查询的解决方案。

SELECT
  p.name,
  (
    SELECT COUNT(*) FROM [page-attachment] pa
    WHERE pa.[PAGE-ID] = p.id
  ) as attachmentsnumber
FROM page p
于 2008-09-17T18:55:40.297 回答
3

根据数据库,为了速度,您可以使用 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 页。UNION 让它在 13 秒内运行,而不是那么长,我感到无聊并尝试了另一种方式(在我杀死外部连接和子查询方法之前的 60 秒以上)。

于 2015-01-27T19:47:05.890 回答
1

您需要左连接,而不是内连接,因为它允许记录不存在。

于 2008-08-31T10:41:26.933 回答
1

左加入是你的朋友。要了解有关不同连接类型的更多信息,请参阅http://en.wikipedia.org/wiki/Join_(SQL)

于 2008-08-31T10:42:11.970 回答
0

用这个:

SELECT p.name,(
    SELECT COUNT(*) FROM [page-attachment] pa WHERE pa.[PAGE-ID] = p.id) as attachmentsnumber
FROM page p
于 2015-01-27T19:51:49.437 回答