将多个计数合并到一个查询中 - group by

发布于 2024-11-19 16:11:09 字数 2184 浏览 2 评论 0原文

我有 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

但组合它们似乎总是返回错误:(操作数应包含 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

所以我尝试从各个语句中删除 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

但是返回所有内容的总计与按用户细分的情况(毫无疑问,因为计数没有说明 where 子句中的用户 ID 或全名)。

我觉得我很接近,但缺少一些东西。有人能在这里指出正确的方向吗?我只是想了解我做错了什么。

感谢您抽出时间。

I have 3 SELECT statements I'd like to combine into one:

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))

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:

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).

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

噩梦成真你也成魔 2024-11-26 16:11:09

最好的方法是使用条件 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

The best way is to use a conditional 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
忆离笙 2024-11-26 16:11:09

我不知道是否可以将这 3 个查询合并为一个统一的查询。您有 3 个重叠的“where 子句”:

第一个查询:落在日期范围内的所有记录
第二个查询:属于该日期范围但状态='C'的所有记录
第三个查询:属于日期范围内但也具有 Caused_change=1 的所有记录

从逻辑角度来说,第一个查询已经包含第二个和第三个查询中的所有记录,因此您将重复计算 #2 和 # 的结果3.

但是,如果您确实想将所有三个结果合并为一个结果,请执行外部查询方法:

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

注意第一个内部查询中 count() 上的别名。这是为了使计数字段在外部查询中显示为“cnt”。

I don't know if you can combine those 3 queries into a single unified query. You've got 3 'where clauses' that overlap:

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'
third query: ALL records that fall in the date range but also have caused_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.

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. That's to make the counted field appear as 'cnt' for the outer query.

狼亦尘 2024-11-26 16:11:09

UNION 和 SUM 应该完成这项工作。您的代码应如下所示:

 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

UNION and SUM should do the work. 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文