简体   繁体   English

将多个计数组合到一个查询中 - 分组依据

[英]combining multiple counts into one query - group by

I have 3 SELECT statements I'd like to combine into one:我有 3 个 SELECT 语句我想合并为一个:

SELECT COUNT(A.id), CONCAT(B.fname,' ', B.lname) AS fullname 
FROM feedbacks A 
    INNER JOIN users B 
         ON A.userid = B.userid 
WHERE DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' 
GROUP BY fullname

SELECT COUNT(A.id), CONCAT(B.fname,' ', B.lname) AS fullname 
FROM feedbacks A 
    INNER JOIN users B 
        ON A.userid = B.userid 
WHERE status = 'C' 
AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' 
GROUP BY fullname`

SELECT COUNT(A.id), CONCAT(B.fname,' ', B.lname) AS fullname 
FROM feedbacks A 
    INNER JOIN users B ON A.userid = B.userid 
WHERE caused_change = 1 
AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' 
GROUP BY fullname

But combining them always seems to return an error: (Operand should contain 1 column(s))但是将它们组合起来似乎总是返回错误:(操作数应包含 1 列)

SELECT 
(SELECT COUNT(A.id), CONCAT(B.fname,' ', B.lname) AS fullname FROM feedbacks A INNER JOIN users B ON A.userid = B.userid WHERE DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' GROUP BY fullname) AS T1,  
(SELECT COUNT(A.id), CONCAT(B.fname,' ', B.lname) AS fullname FROM feedbacks A INNER JOIN users B ON A.userid = B.userid WHERE status = 'C' AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' GROUP BY fullname) AS T2,  
(SELECT COUNT(A.id), CONCAT(B.fname,' ', B.lname) AS fullname FROM feedbacks A INNER JOIN users B ON A.userid = B.userid WHERE caused_change = 1 AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' GROUP BY fullname) AS T3

So I tried removing the JOIN and GROUP from the individual statements to make:因此,我尝试从各个语句中删除 JOIN 和 GROUP 以进行:

SELECT CONCAT(B.fname, ' ', B.lname) AS fullname,
(SELECT COUNT(A.id) FROM feedbacks A WHERE DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11') AS T1,  
(SELECT COUNT(A.id) FROM feedbacks A WHERE status = 'C' AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11') AS T2,
(SELECT COUNT(A.id) FROM feedbacks A WHERE caused_change = 1 AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11') AS T3
FROM feedbacks 
    INNER JOIN users B 
        ON feedbacks.userid = B.userid 
GROUP BY fullname

But that returns totals for everything vs. breakdown by user (because the counts don't say anything about userid or fullname in the where clause, no doubt).但这会返回所有内容的总数与用户细分的总数(因为毫无疑问,计数在 where 子句中没有说明用户 ID 或全名的任何内容)。

I feel like I'm close but missing something.我觉得我很接近但错过了一些东西。 Can anyone point me in the correct direction here?谁能在这里指出我正确的方向? I'm just trying to learn what I'm doing wrong.我只是想知道我做错了什么。

Thank you for your time.感谢您的时间。

The best way is to use a conditional SUM :最好的方法是使用条件SUM

SELECT CONCAT(B.fname, ' ', B.lname) AS fullname,
       SUM(
           CASE WHEN DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' 
           THEN 1 ELSE 0 END
       ) AS T1,
       SUM(
           CASE WHEN status = 'C' 
                 AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' 
           THEN 1 ELSE 0 END
       ) AS T2,
       SUM(
           CASE WHEN caused_change = 1 
                 AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' 
           THEN 1 ELSE 0 END
       ) AS T3
FROM feedbacks 
    INNER JOIN users B 
        ON feedbacks.userid = B.userid 
GROUP BY fullname

I don't know if you can combine those 3 queries into a single unified query.我不知道您是否可以将这 3 个查询合并为一个统一查询。 You've got 3 'where clauses' that overlap:您有 3 个重叠的“where 子句”:

first query: ALL records that fall in the date range第一个查询:日期范围内的所有记录
second query: ALL records that fall in the date range but also have status='C'第二个查询:在日期范围内但也有 status='C' 的所有记录
third query: ALL records that fall in the date range but also have caused_change=1第三个查询:在日期范围内但也有 cause_change=1 的所有记录

In logical terms, the first query already contains all the records from the second and third queries, so you'd be double counting the results from #2 and #3.从逻辑上讲,第一个查询已经包含了来自第二个和第三个查询的所有记录,因此您将重复计算来自 #2 和 #3 的结果。

However, if you do want to combine all three into a single result, then do the outer query method:但是,如果您确实想将所有三个组合成一个结果,请执行外部查询方法:

SELECT sum(cnt), fullname
FROM (
    SELECT COUNT(A.id) as cnt, CONCAT(B.fname,' ', B.lname) AS fullname
    FROM feedbacks A
    INNER JOIN users B ON A.userid = B.userid
    WHERE DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11'
    GROUP BY fullname

    UNION

    ...
    WHERE status = 'C' AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11'

    UNION

    ...
    WHERE caused_change = 1 AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11'
) AS innerquery
GROUP BY fullname

Note the alias on the count() in the first inner query.请注意第一个内部查询中count()的别名。 That's to make the counted field appear as 'cnt' for the outer query.这是为了使计数字段在外部查询中显示为“cnt”。

UNION and SUM should do the work. UNION 和 SUM 应该做这项工作。 Your code should look like this:您的代码应如下所示:

 select sum(x.col1), x.fullname
from
(SELECT COUNT(A.id)as col1, CONCAT(B.fname,' ', B.lname) AS fullname FROM feedbacks A INNER JOIN users B ON A.userid = B.userid WHERE DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' GROUP BY fullname
UNION
SELECT COUNT(A.id)as col1, CONCAT(B.fname,' ', B.lname) AS fullname FROM feedbacks A INNER JOIN users B ON A.userid = B.userid WHERE status = 'C' AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' GROUP BY fullname
UNION
SELECT COUNT(A.id)as col1, CONCAT(B.fname,' ', B.lname) AS fullname FROM feedbacks A INNER JOIN users B ON A.userid = B.userid WHERE caused_change = 1 AND DATE(origindate) BETWEEN '2011-03-01' AND '2011-07-11' GROUP BY fullname
)x
group by x.fullname

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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