[英]Count records in each category
I have two tables: 我有两个表:
ci_categories
with fields cat_id
, cat_name
, cat_slug
etc. 具有字段cat_id
, cat_name
, cat_slug
等。
ci_albums
with fields cat_id
, album_id
, album_name
etc. 包含字段cat_id
, album_id
, album_name
等。
I want to join these two tables, display category listing, and COUNT albums in each category. 我想加入这两个表,分别显示类别列表和每个类别中的COUNT个相册。 Like: 喜欢:
Category 1 - 20 Albums 第1-20类专辑
Category 2 - 25 Albums 类别2-25个专辑
How is this done properly in PostgreSQL? 如何在PostgreSQL中正确完成?
The following query should get you what you want: 以下查询将为您提供所需的信息:
SELECT c.cat_id, COUNT(a.album_id)
FROM ci_categories AS c
LEFT JOIN ci_albums AS a ON c.cat_id = a.cat_id
GROUP BY c.cat_id
We use a LEFT JOIN
here due to the possibility of categories which contain no albums. 由于此处的类别不包含专辑,因此我们在此处使用LEFT JOIN
。 If you don't care if those results show up, just change this to an INNER JOIN
. 如果您不在乎这些结果是否出现,只需将其更改为INNER JOIN
。
We use the aggregate COUNT(a.album_id)
function to count the number of records. 我们使用汇总COUNT(a.album_id)
函数对记录数进行计数。 By grouping by the c.cat_id
, we make sure this count is done only over records of the same type. 通过按c.cat_id
分组,我们确保仅对相同类型的记录进行此计数。 If there is no album for that category, a.album_id will be NULL, and so COUNT
will not include it in the total count. 如果没有该类别的专辑,则a.album_id将为NULL,因此COUNT
不会将其包括在总数中。
select c.cat_name,
count(distinct a.album_id) as albums
from ci_categories c
left join ci_albums a on a.cat_id = c.cat_id
group by c.cat_name
SELECT ci_categories.cat_name, COUNT(*) as count
FROM ci_categories JOIN ci_albums ON ci_categories.cat_id = ci_albums.cat_id
GROUP BY ci_categories.cat_name;
The other answers are somewhat equal with some slight differences, notably the DISTINCT
in the COUNT
and the aliasing of the tables. 其他答案在某种程度上是相等的,但有一些细微的差异,特别是COUNT
的DISTINCT
和表的别名。
EDIT / WARNING 编辑/警告
Well, my answer is actually wrong, due to the fact that a JOIN
will also include a categories if there are no albums in that category. 好吧,我的回答实际上是错误的,因为如果该类别中没有专辑,那么JOIN
也将包含一个类别。 That category is then joined to NULL
values, which are counted by COUNT(*)
anyways. 然后,该类别将与NULL
值连接,无论如何都将由COUNT(*)
进行计数。 Leaving this one here as an example of a common mistake. 将此示例留在此处是一个常见错误的示例。
If you are satisfied with cat_id
and the count of albums in the result, you don't need the table ci_categories
in your query at all. 如果您对cat_id
和结果中的相册数量感到满意,则查询中根本不需要表ci_categories
。 Use this simpler and faster query: 使用以下更简单,更快速的查询:
SELECT cat_id, count(*) AS albums
FROM ci_albums
GROUP BY 1;
Assuming proper table definitions without duplicate entries. 假设正确的表定义没有重复的条目。
This does not includes categories with no albums at all. 这不包括完全没有相册的类别。 Only if you need those - too, or if you need additional information from the table ci_categories
itself - only then you need to join to that table. 仅当您也需要这些信息时,或者需要ci_categories
表本身的其他信息时,才需要加入该表。 But since we are counting everything , it is faster to aggregate first and join later: 但是由于我们正在计算所有内容 ,因此先进行汇总然后再进行合并的速度更快:
SELECT c.cat_id, c.cat_name, COALESCE(a.albums, 0) AS albums
FROM ci_categories c
LEFT JOIN (
SELECT cat_id, count(*) AS albums
FROM ci_albums
GROUP BY 1
) a USING (cat_id);
LEFT JOIN
if you want categories with 0 albums, too. LEFT JOIN
如果您也想要包含0个相册的类别。 Else, just JOIN
. 否则,只需JOIN
。
COALESCE
is only needed if you need 0
instead of NULL
in the result. 仅当结果中需要0
而不是NULL
时才需要COALESCE
。
Test performance with EXPLAIN ANALYZE
if you care. 如果需要,可以使用EXPLAIN ANALYZE
测试性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.