MySQL:查询应该返回计数为0的行

时间:2013-10-21 14:50:16

标签: mysql sql

我有2个表 - 用户和部门以及按部门返回用户数的查询。如果用户没有部门返回"没有部门"。但我还需要没有用户的部门作为计数 0 。 这是我的问题:

SELECT COALESCE(departments.name, 'No department') AS name, count( * ) AS count
FROM users
LEFT JOIN departments ON departments.id = users.department_id
WHERE users.is_deleted = 0
AND users.company_id = 1
AND (TIMESTAMPDIFF(YEAR, `date_of_birth`, CURDATE()) BETWEEN 1 AND 18 )
GROUP BY departments.name

它应该是这样的:

________________________
  Dep name  |  count    |
________________________
Dep 1       | 2         |
________________________
Dep 2       | 3         |
________________________
Dep 3       | 0         | if users  in this department not exist
________________________
No dep      | 1         | if users not have department
________________________

请帮帮我,伙计们!

我找到了解决方案

SELECT   COALESCE(locations.name, 'Without location')  AS location,
            COUNT(IF(TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) BETWEEN 1 AND 17, 1, NULL)) 'group_1_17'

          FROM users
          LEFT JOIN locations ON locations.id = users.location_id
          WHERE users.is_deleted = 0 AND users.company_id = :company_id
          GROUP BY locations.name

          UNION

          SELECT
            locations.name AS location,
            0 'group_1_17'         
          FROM users
          RIGHT JOIN locations ON locations.id = users.location_id
          WHERE locations.company_id = :company_id AND users.id IS NULL"

3 个答案:

答案 0 :(得分:3)

having count(*) = 0

这是聚合的“位置”。

SELECT COALESCE(departments.name, 'No department') AS name, count( * ) AS count
FROM users
LEFT JOIN departments ON departments.id = users.department_id
WHERE users.is_deleted = 0
AND users.company_id = 1
AND (TIMESTAMPDIFF(YEAR, `date_of_birth`, CURDATE()) BETWEEN 1 AND 18 )
GROUP BY departments.name
HAVING COUNT(*) = 0

答案 1 :(得分:0)

SELECT CASE WHEN COUNT_DEPTS=0
            THEN 'No department'
            ELSE NAME
        END ,
        COUNT_DEPTS  
FROM
(
    SELECT
       D..NAME,COUNT(D.ID) COUNT_DEPTS
      FROM USERS U
      LEFT OUTER JOIN 
           DEPARTMENTS D 
      ON U.DEPARTMENT_ID = D.ID
     WHERE U.IS_DELETED = 0
       AND U.COMPANY_ID = 1
       AND (TIMESTAMPDIFF(YEAR, `date_of_birth`, CURDATE()) BETWEEN 1 AND 18 )
    GROUP BY D.NAME
);

答案 2 :(得分:0)

根据我的理解,您需要没有没有用户的部门部门的用户。你的左连接将给你后者,但不是前者。要获得两者,您需要full join。但MySQL不支持完全连接。即使它确实如此,where子句中的条件也会消除完整连接的“正确”部分。

因此除了emulating a full join之外,我能想到的唯一方法是使用union“手动”追加未填充的部门,计数为零:

SELECT COALESCE(departments.name, 'No department') AS name, count( * ) AS count
FROM users
LEFT JOIN departments ON departments.id = users.department_id
WHERE users.is_deleted = 0
AND users.company_id = 1
AND (TIMESTAMPDIFF(YEAR, `date_of_birth`, CURDATE()) BETWEEN 1 AND 18 )
GROUP BY departments.name
UNION
SELECT name,0 FROM departments
WHERE id NOT IN (
  SELECT department_id FROM users
  WHERE department_id IS NOT NULL
  )

不是那么优雅,被授予,但它做了肮脏的工作......