1

我有 2 个表 - 用户和部门,以及按部门返回用户计数的查询。如果用户没有返回“无部门”的部门。但是我还需要将没有用户的部门作为 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

它应该是这样的:

________________________
  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"
4

3 回答 3

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
于 2013-10-21T14:53:25.190 回答
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
);
于 2013-10-21T15:02:53.340 回答
0

据我了解,您既需要没有部门的用户,也需要没有用户的部门。你的左连接会给你后者,但不是前者。为了两者兼得,您需要一个full join. 但是 MySQL 不支持完全连接。即使是这样,您的where子句中的条件也会消除完全连接的“正确”部分。

因此,除了模拟完全连接之外,我能想到的唯一方法是“手动”附加未填充的部门,计数为零,使用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
  )

不那么优雅,理所当然,但它做了肮脏的工作......

于 2013-10-21T17:42:43.883 回答