如何更有效地编写以下MySQL查询?

时间:2016-09-02 21:11:47

标签: mysql

以下是用户表, id 是主键。 [与出席率表格的一对多关系

+------------+-----------------+
| id |  name |     created     |
+------------+-----------------+
| 1  | Sumon |     2015-01-10  |
+------------+-----------------+
| 2  | James |     2015-01-11  |
+------------+-----------------+
| ...| ...   |     ...         |
+------------+-----------------+

这是另一张表参加者。此处 id 是主键, user_id 用户

的外键
+--------------+------+--------+-----------------+
| id | user_id | year | month  |     created     |
+--------------+------+--------+-----------------+
| 1  | 2       | 2015 | 1      |     2015-01-10  |
+--------------+---------------+-----------------+
| 2  | 1       | 2016 | 2      |     2016-02-10  |
+--------------+------+--------+-----------------+
| 3  | 1       | 2016 | 2      |     2016-02-11  |
+--------------+------+--------+-----------------+
| ...| ...     | ...  | ...    |     ...         |
+--------------+------+--------+-----------------+

我当前的MySQL查询

SELECT COUNT(DISTINCT user_id) AS january,
(SELECT COUNT(DISTINCT user_id) FROM attendances WHERE year='2016' AND month=2) as february,
(SELECT COUNT(DISTINCT user_id) FROM attendances WHERE year='2016' AND month=3) as march,
...
...
(SELECT COUNT(DISTINCT user_id) FROM attendances WHERE year='2016' AND month=12) as december
FROM attendances WHERE year='2016' AND month=1

我上面的MySQL查询结果如下所示

+---------+----------+-------+-------+-----+-------+------+--------+-----------+---------+----------+----------+
| january | february | march | april | may | june  | july | august | september | october | november | december |
+---------+----------+-------+-------+-----+-------+------+--------+-----------+---------+----------+----------+
| 24      | 17       | 20    | 0     | 24  | 23    | 19   | 24     | 13        | 0       | 0        | 0        |
+---------+----------+-------+-------+-----+-------+------+--------+-----------+---------+----------+----------+

有没有办法更有效地编写同一个查询?

2 个答案:

答案 0 :(得分:2)

您可以使用CASE WHEN

SELECT COUNT(DISTINCT (CASE WHEN month = 1 THEN user_id END)) as january,
       COUNT(DISTINCT (CASE WHEN month = 2 THEN user_id END)) as february,
       COUNT(DISTINCT (CASE WHEN month = 3 THEN user_id END)) as march

FROM   attendances
WHERE  year='2016'

答案 1 :(得分:1)

使用group by

select count(DISTINCT user_id), year, MONTHNAME(STR_TO_DATE(month, '%m'))
from attendances
where year='2016'
group by month
order by month