一尘不染

单个SQL查询中的多个计数

sql

我正在尝试使用以下代码来获取4个特定部分中的文档数:

SELECT
    category.id
    , category.title
    , count(ts1.section_id) AS doc1
    , count(ts2.section_id) AS doc2
    , count(ts3.section_id) AS doc3
    , count(ts4.section_id) AS doc4
FROM
    category 
    LEFT JOIN category_link_section AS ts1
        ON (category.id = ts1.category_id AND ts1.section_id = 1)
    LEFT JOIN category_link_section AS ts2
        ON (category.id = ts2.category_id AND ts2.section_id = 2)
    LEFT JOIN category_link_section AS ts3
        ON (category.id = ts3.category_id AND ts3.section_id = 3)
    LEFT JOIN category_link_section AS ts4
        ON (category.id = ts4.category_id AND ts4.section_id = 4)
GROUP BY category.id, ts1.section_id, ts2.section_id, ts3.section_id, ts4.section_id

表“ category”具有ID,标题等。表“
category_link_section”包含category_id,section_id和doc_id之间的ID链接。

如果任何列的计数为0,则在该列中显示0。但是,如果结果不为0,则显示所有分段结果的相乘结果。因此,如果我的4个计数列应该返回:1、2、0、3;它实际上将显示6、6、0、6;

如果我对每个特定类别使用以下代码,则会得到想要的结果:

SELECT
    category.id
    , category.title
    , count(ts1.section_id) AS doc1
FROM
    category 
    LEFT JOIN category_link_section AS ts1
        ON (category.id = ts1.category_id AND ts1.section_id = 1)
GROUP BY category.id, ts1.section_id

但是随后我需要为每个部分每次都遍历数据库。

所以我的问题是,我是否需要逐步执行并依次调用每个部分,在SQL外部构造表,还是可以在单个查询中完成?


阅读 208

收藏
2021-03-17

共1个答案

一尘不染

@VoteyDisciple的答案是正确的,但是他的查询需要一些改进:

SELECT c.id, c.title,
    SUM(ts1.section_id = 1) AS doc1,
    SUM(ts1.section_id = 2) AS doc2,
    SUM(ts1.section_id = 3) AS doc3,
    SUM(ts1.section_id = 4) AS doc4
FROM category AS c
  LEFT JOIN category_link_section AS ts1
    ON (c.id = ts1.category_id)
GROUP BY c.id;

说明:

  • 这些IF()表达式是多余的,因为相等已经返回1或0。
  • ts1.section_id=1出来的连接条件,否则你将永远不会得到其他section_id值。
  • c.id仅分组。我假设OP每个类别只需要一行,而section_id各个类别的每个值的计数则需要一列。如果查询按进行分组c.id, ts1.section_id,则每个类别最多有四行。
  • 在选择列表中移动逗号。一行开头的逗号看起来很难看。;-)
2021-03-17