MySQL数据库中有很多方式实现行转列,在面试中也是经常考的SQL语句。
这个问题的本质其实就是如何实现行转列(How to count values on a pivot table in MySQL)。
原问题:
I have two tables Users and Get_cal like below :
id_user(pk) | com |
1004 | 700 |
1005 | 700 |
1006 | 700 |
1010 | 701 |
1011 | 701 |
1012 | 701 |
1013 | 701 |
1014 | 800 |
1015 | 800 |
1016 | 800 |
1017 | 800 |
id_user(fk) | status |
1004 | ABAN |
1004 | ABAN |
1004 | DES |
1004 | LET |
1004 | DES |
1004 | ABAN |
1011 | LET |
1011 | LET |
1011 | ABAN |
1015 | ABAN |
1015 | DES |
1015 | LET |
1015 | LET |
For status column I have 5 types (ABAN,DES,LET,NOANS,OTH). I want to get this result like below(Get the count by user by status ):
d_user | ABAN | DES | LET | NOANS | OTH |
1004 | 3 | 2 | 1 | 0 | 0 |
1005 | 0 | 0 | 0 | 0 | 0 |
1006 | 0 | 0 | 0 | 0 | 0 |
1010 | 0 | 0 | 0 | 0 | 0 |
1011 | 1 | 0 | 2 | 0 | 0 |
1012 | 0 | 0 | 0 | 0 | 0 |
1013 | 0 | 0 | 0 | 0 | 0 |
1014 | 0 | 0 | 0 | 0 | 0 |
1015 | 1 | 1 | 2 | 0 | 0 |
1016 | 0 | 0 | 0 | 0 | 0 |
1017 | 0 | 0 | 0 | 0 | 0 |
I have no idea how to start the query, please any suggestion?
采纳答案
You want conditional aggregation here:
SELECT
u.id_user,
COUNT(CASE WHEN c.status = 'ABAN' THEN 1 END) AS ABAN,
COUNT(CASE WHEN c.status = 'DES' THEN 1 END) AS DES,
COUNT(CASE WHEN c.status = 'LET' THEN 1 END) AS LET,
COUNT(CASE WHEN c.status = 'NOANS' THEN 1 END) AS NOANS,
COUNT(CASE WHEN c.status NOT IN ('ABAN', 'DES', 'LET', 'NOAN')
THEN 1 END) AS OTH
FROM Users u
LEFT JOIN Get_cal c
ON c.id_user = u.id_user
GROUP BY
u.id_user
ORDER BY
u.id_user;
问题解析
该问题主要目的就是想将结果行显示为列也就是行转列,通过case when
的方式实现也是最简单的。这里面因为明确status只有五种,所以最后一种status才通过排除其他status的方式进行展示,其实直接写OTH反而比较好,因为不是每个用户都有相关状态所以需要使用Left join
。具体运行结果可以查看 dbfiddle
本文根据StackOverflow翻译而来,不代表烟海拾贝立场,如若转载,请注明出处:https://somirror.com/554.html