2011-03-17 79 views
2

我一直在尝试不同的方法来处理这个问题,但我没有多少运气。有选择的条件计数/总和

基本上这个查询返回一个员工所建立的所有目录。我需要添加一个字段到这个查询的选择中,该字段列出了有多少个具有'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 

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

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

回答

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 
+0

真棒谢谢! - 我只尝试过第二个例子 - 它完美地工作(超过了我目前的技能水平)。一个小类型o在第二行:'AdminDir.AdminAcount'应该是'AdminDir.AdminCount。 – Reno 2011-03-17 17:06:14

+0

@Reno - 很高兴能帮到你。我会解决你提到的错字。 – Thomas 2011-03-17 17:20:35

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 

这样的领域只会增加1时u.access_level = 'admin',如果它不是那么它将增加0 - 这当然意味着它不会指望它

+0

这是接近我的失败尝试实际上之一。这样做只返回一行,列出第一个找到的目录和所有目录中所有者的总数。谢谢你! – Reno 2011-03-17 16:54:38

+0

@Reno:这很简单,然后 - 简单地按d.id'字段进行分组,每个目录显示一个结果 – BigFatBaby 2011-03-17 17:26:27

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 
+0

与BigFatBaby示例相同的问题:这样做只会返回员工有权访问的第一个目录与他们有权访问的所有目录中的管理员总数。谢谢你! – Reno 2011-03-17 16:56:27

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

编辑。请注意,这种情况下甚至可以以这种方式

sum(u.access_level = 'admin') 

因为MySQL只返回1,如果条件为真0,如果是没有被改写。