[英]combining multiple counts into one query - group by
我有 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 或全名的任何內容)。
我覺得我很接近但錯過了一些東西。 誰能在這里指出我正確的方向? 我只是想知道我做錯了什么。
感謝您的時間。
最好的方法是使用條件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
我不知道您是否可以將這 3 個查詢合並為一個統一查詢。 您有 3 個重疊的“where 子句”:
第一個查詢:日期范圍內的所有記錄
第二個查詢:在日期范圍內但也有 status='C' 的所有記錄
第三個查詢:在日期范圍內但也有 cause_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”。
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.