簡體   English   中英

MySQL Count 和 Convert Row to Colum 只涉及一張表

[英]MySQL Count and Convert Row to Colum Involve One Table Only

我有一個記錄用戶活動的表名歷史記錄,它由 user_id、branch_id 和持續時間組成。

該表如下所示:

+++++++++++++++++++++++++++++++++++
id | user_id | branch_id | totHours
+++++++++++++++++++++++++++++++++++
|1 |   100   |     1     |    1   |
|2 |   199   |     1     |    1   |
|3 |   121   |     1     |    1   |
|4 |   140   |     1     |    1   |
|5 |   103   |     2     |    3   |
|6 |   107   |     2     |    1   |
|7 |   299   |     1     |    2   |
|8 |   209   |     2     |    2   |
|9 |   119   |     1     |    5   |

我想產生這樣的輸出:

+++++++++++++++++++++++++++
Hours | Branch A | Branch B
+++++++++++++++++++++++++++
|1    |    4    |     1   |
|2    |    1    |     1   |
|3    |    0    |     1   |
|4    |    0    |     0   |
|5    |    1    |     0   |

我嘗試使用此查詢進行操作,但是當我僅在 totHours 列上使用 group by 時,它會返回錯誤,因為我需要在 group by 中包含 branch_id。

這是我的查詢:

select totHours as Hours,
   coalesce(case when branch_id = 1 then count(totHours) else 0 end) as 'Branch A',
   coalesce(case when branch_id = 2 then count(totHours) else 0 end) as 'Branch B'
from histories
group by totHours, branch_id;

如果 totHours 不在表中(例如在此表 4 中),則兩個分支列都將顯示 0。

這是我的數據庫小提琴

更新:MySQL 版本 5.7.22

如果您使用 MySQL 版本 8+(或任何版本支持 windows 功能),您可以使用遞歸公用表表達式為您生成小時值,然后使用它LEFT JOINhistories 之后,您可以在SELECT中使用CASE表達式執行SUM()以生成預期的輸出:

WITH RECURSIVE hours AS (
    SELECT 1 AS hr, MAX(totHours) AS maxth FROM histories UNION ALL
    SELECT hr+1, maxth FROM hours WHERE hr+1 <= maxth)
SELECT hours.hr, 
       SUM(CASE WHEN histories.branch_id=1 THEN 1 ELSE 0 END) AS Branch_A,
       SUM(CASE WHEN histories.branch_id=2 THEN 1 ELSE 0 END) AS Branch_B
FROM hours
 LEFT JOIN histories 
 ON hours.hr=histories.totHours
GROUP BY hours.hr;

如果您使用的版本不支持窗口函數,您可以創建一個子查詢來表示小時數(包括缺少的小時數)。 這是一種硬編碼方法,您可能必須始終更新子查詢以包含新的小時值(如果有):

SELECT hours.hr, 
       SUM(CASE WHEN histories.branch_id=1 THEN 1 ELSE 0 END) AS Branch_A,
       SUM(CASE WHEN histories.branch_id=2 THEN 1 ELSE 0 END) AS Branch_B
FROM 
    (SELECT 1 hr UNION 
      SELECT 2 UNION 
      SELECT 3 UNION 
      SELECT 4 UNION 
      SELECT 5) AS hours
 LEFT JOIN histories 
 ON hours.hr=histories.totHours
GROUP BY hours.hr;

演示小提琴

編輯hours子查詢以添加更多內容,例如,如果您想要直到 7 點,您只需添加:

(SELECT 1 hr UNION 
      SELECT 2 UNION 
      SELECT 3 UNION 
      SELECT 4 UNION 
      SELECT 5 UNION 
      SELECT 6 UNION 
SELECT 7) AS hours

到子查詢。 另一種方法是預先定義小時數並創建參考表。 假設您估計小時為 100,那么最好創建一個存儲 1-100 的表作為LEFT JOIN的參考

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM