单个SQL查询中的多个计数

时间:2009-08-13 01:53:09

标签: sql mysql join count

我正在尝试使用以下代码获取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,3,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之外构建我的表,还是可以在一个查询中完成?

2 个答案:

答案 0 :(得分:26)

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

答案 1 :(得分:6)

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

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