选择中的条件计数/总和

时间:2011-03-17 16:38:16

标签: mysql

我一直在尝试不同的方式来解决这个问题,但我没有太多运气。

这个查询基本上会返回员工内置的所有目录。我需要在此查询的选择中添加一个字段,该字段列出了在目录中内置了“admin”访问权限(u.access_level)的其他用户数量。

Table:  Directories (has many users)
Table:  Users (users of the directory with different access levels)

SELECT d.id, d.name, u.employee_number, u.access_level, u.id 'user_id', 
(** count of all users of this directory where their u.access_level = 'admin) AS admins 
FROM directories d JOIN users u ON d.id = u.directory_id 
WHERE u.employee_number = '045283' 
ORDER BY d.NAME 

因此,我需要返回构建员工的所有目录的记录集,包括对每个目录具有“admin”访问权限的用户总数。基本上我需要计算一些后来的框架逻辑,比如“如果员工是这个目录的最后一个管理员 - 不允许他们自己删除或更改他们的访问级别 - 首先将另一个用户升级到管理员级别。”

感觉我需要一个子查询,但现在这有点超出我的SQL技能。谢谢你的帮助!

4 个答案:

答案 0 :(得分:14)

sum(if(u.access_level = 'admin',1,0)) as admins

修改。请注意,即使以这种方式也可以重写此条件

sum(u.access_level = 'admin')

因为如果condition为true,mysql只返回1,如果不是则返回0。

答案 1 :(得分:2)

试试这个:

SELECT d.id, d.name, u.employee_number, u.access_level, u.id 'user_id', 
SUM(IF(u.access_level = 'admin',1,0)) AS admins 
FROM directories d JOIN users u ON d.id = u.directory_id 
WHERE u.employee_number = '045283' 
ORDER BY d.NAME

这样,字段只会在u.access_level = 'admin'时加1,如果不是那么它会加0 - 这当然意味着它不计算

答案 2 :(得分:1)

你会找到这样的东西:

SELECT d.id, d.name, u.employee_number, u.access_level, u.id 'user_id', 
SUM(IF(u.access_level = 'admin',1,0)) AS admins
FROM directories d JOIN users u ON d.id = u.directory_id 
WHERE u.employee_number = '045283' 
ORDER BY d.NAME 

答案 3 :(得分:1)

Select d.id, d.name, u.employee_number, u.access_level, u.id 'user_id'
    , (Select Count(*)
        From directories As D1
            Join users As U1
                On U1.directory_id = D1.id
        Where U1.access_level = 'admin'
            And D1.id = D.id) As AdminUsers
From directories As D
    Join users As U
        On U.directory_id = D.id
Where u.employee_number = '045283'
Order By d.Name

使用派生表的另一种解决方案(可能表现更好):

Select d.id, d.name, u.employee_number, u.access_level, u.id 'user_id'
    , Coalesce(AdminDir.AdminCount,0) As AdminCount
From directories As D
    Join users As U
        On U.directory_id = D.id
    Left Join   (
                Select D1.id, Count(*) As AdminCount
                From directories As D1
                    Join users As U1
                        On U1.directory_id = D1.id
                Where U1.access_level = 'admin'
                Group By D1.id  
                ) As AdminDir
            On AdminDir.id = D.id
Where u.employee_number = '045283'
Order By d.Name