根据值为groupby动态字段返回唯一的非重复值

wkyowqbh  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(312)

这个问题在这里已经有答案了

多个查询同一个表但在不同的列中mysql(4个答案)
11个月前关门了。
我有以下sql查询:

SELECT DISTINCT
    username,
    (CASE WHEN role_id = 1 THEN SUM(user_roles.hours) ELSE NULL END) AS `Admin`,
    (CASE WHEN role_id = 2 THEN SUM(user_roles.hours) ELSE NULL END) AS `Subscriber`
FROM user_roles
LEFT JOIN users ON users.id = user_roles.user_id;

此查询的目的是在每行上显示用户名,并为每个用户名显示管理员、订阅者等的小时数。
此查询生成以下结果:

username    Admin    Subscriber
abc         10       0
abc         0        5
def         0        7
def         4        0

每个用户名都应该有一个唯一的值,该值属于admin或subscriber(没有用户可以同时拥有这两个值)
我希望输出为:

username    Admin    Subscriber
abc         10       5
def         4        7

其中没有显示零的列,并且每个用户名只有一行结果。
我希望很清楚我在这里要完成什么。
谢谢你的帮助

7fhtutme

7fhtutme1#

我想你把连接点改过来了。
你应该做一个左连接 usersuser_roles 并使用条件聚合:

SELECT 
    u.username,
    SUM(CASE WHEN r.role_id = 1 THEN r.hours ELSE 0 END) AS `Admin`,
    SUM(CASE WHEN r.role_id = 2 THEN r.hours ELSE 0 END) AS `Subscriber`
FROM users u LEFT JOIN user_roles r 
ON u.id = r.user_id
GROUP BY u.username
oxiaedzo

oxiaedzo2#

这回答了您最初提出的问题。
您需要条件聚合。“condition”是聚合函数的参数。但您也可以将其简化为:

SELECT u.username,
       SUM(ur.role_id = 1) AS `Admin`,
       SUM(ur.role_id = 2) AS `Subscriber`
FROM user_roles ur LEFT JOIN
     users u
     ON u.id = ur.user_id
GROUP BY u.username, u.id;

这使用了一个mysql快捷方式,您可以将一个布尔值相加,得到“true”s的计数。另外,我还包括 idGROUP BY 以防用户同名。很明显,如果你知道的话,这是不需要的 username 是独一无二的。
如果要对另一列求和,则 CASE 需要表达式:

SELECT u.username,
       SUM(CASE WHEN ur.role_id = 1 THEN ur.hours ELSE 0 END) AS `Admin`,
       SUM(CASE WHEN ur.role_id = 2 THEN ur.hours ELSE 0 END) AS `Subscriber`
FROM user_roles ur LEFT JOIN
     users u
     ON u.id = ur.user_id
GROUP BY u.username, u.id;

相关问题