单个 SQL 查询中的多个计数

Posted

技术标签:

【中文标题】单个 SQL 查询中的多个计数【英文标题】:Multiple counts within a single SQL query 【发布时间】:2010-11-19 04:06:07 【问题描述】:

我正在尝试使用以下代码获取 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

表“类别”有一个 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 之外构建我的表,还是可以在单个查询中完成?

【问题讨论】:

【参考方案1】:

@VoteyDisciple 的answer 是在正确的轨道上,但他的查询需要一些改进:

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 分组,则每个类别最多有四行。 在选择列表中移动逗号。在行首浮动的逗号看起来很难看。 ;-)

【讨论】:

你能解释一下改进吗? 太棒了!谢谢。奇迹般有效。 :) 我仍然会使用前面的逗号。帮助我查看语法错误在哪里。 ;) 再次感谢。 我真正想要解释的是 Sum(布尔条件)模式。那很整洁。那是只有 mysql 的吗? 布尔表达式在我使用的每个 SQL 数据库中总是产生 1 或 0。严格来说,在标准 SQL 中它们应该是 truefalse,但实际上它们只是整数 1 或 0。【参考方案2】:

你可能想尝试这样的事情:

SELECT
    category.id
    , category.title
    , SUM(IF(ts1.section_id = 1, 1, 0)) AS doc1
    , SUM(IF(ts1.section_id = 2, 1, 0)) AS doc2
    , SUM(IF(ts1.section_id = 3, 1, 0)) AS doc3
    , SUM(IF(ts1.section_id = 4, 1, 0)) AS doc4
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 查询中的多个计数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用单个查询获取存储在不同变量中的多个表行的计数?

如何使用 sql 中的单个查询获取项目计数和总计数?

如何使用具有多个连接的 SQL 查询并使用休眠计数

sql [sql]使用日期过滤计算1个查询中的多个计数

SQL Server 同一查询中的多个计数 - CosmosDB

SQL 查询:计数,按月-年分组,具有多个日期字段