简体   繁体   English

计算每个类别中的记录

[英]Count records in each category

I have two tables: 我有两个表:

ci_categories
with fields cat_id , cat_name , cat_slug etc. 具有字段cat_idcat_namecat_slug等。

ci_albums
with fields cat_id , album_id , album_name etc. 包含字段cat_idalbum_idalbum_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. 其他答案在某种程度上是相等的,但有一些细微的差异,特别是COUNTDISTINCT和表的别名。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM