我正在使用名为appointments
的表,这些列是:
scheduled_at:日期时间 doctor_id:整数 说明:文字 finish_at:datetime
我想获得按doctor_id
分组以及按一组日期间隔分组的所有约会的计数,这些日期间隔根据给定的输入集而变化。我得到的输入是:from
是日期,to
是日期。
我要解决的第一个用例是将给定的from
和to
中的结果按月划分。因此,如果给我from
='2018-02-03'和to
='2018-10-03',我想获取为每个医生完成的所有约会的COUNT,并且从2018-02
到2018-10
的每个月。
我知道如何按Doctor_id进行分组,但是我不知道如何对这些动态日期间隔进行分组。
这是我到目前为止所拥有的:
SELECT COUNT(*)
FROM appointments
WHERE finished_at IS NOT NULL
GROUP BY doctor_id
我知道,如果事先有间隔,我可以进行尽可能多的查询,因此最终我每个月都要进行一次查询,例如:
SELECT COUNT(*)
FROM appointments
WHERE finished_at IS NOT NULL
AND scheduled_at BETWEEN '2018-02-01' AND '2018-03-01'
GROUP BY doctor_id
SELECT COUNT(*)
FROM appointments
WHERE finished_at IS NOT NULL
AND scheduled_at BETWEEN '2018-03-01' AND '2018-04-01'
GROUP BY doctor_id
我只是想知道是否有一种方法可以在SQL中做到这一点,所以我只需要执行一个查询。
答案 0 :(得分:1)
您可以使用条件聚合:
SELECT doctor_id,
SUM(CASE WHEN scheduled_at BETWEEN '2018-02-01' AND '2018-03-01' THEN 1 ELSE 0 END),
SUM(CASE WHEN scheduled_at BETWEEN '2018-03-01' AND '2018-04-01' THEN 1 ELSE 0 END)
FROM appointments
WHERE finished_at IS NOT NULL
GROUP BY doctor_id
答案 1 :(得分:1)
使用case
表达式进行条件聚合:
SELECT doctor_id,
COUNT(*),
COUNT(case when scheduled_at BETWEEN '2018-02-01' AND '2018-03-01' then 1 end),
COUNT(case when scheduled_at BETWEEN '2018-03-01' AND '2018-04-01' then 1 end)
FROM appointments
WHERE finished_at IS NOT NULL
GROUP BY doctor_id
或者也有group by
年和月的查询:
SELECT doctor_id, year(scheduled_at), month(scheduled_at), COUNT(*)
FROM appointments
WHERE finished_at IS NOT NULL
GROUP BY doctor_id, year(scheduled_at), month(scheduled_at)
或者,也许应该使用ANSI SQL函数EXTRACT
:
SELECT doctor_id,
extract(year from scheduled_at), extract(month from scheduled_at), COUNT(*)
FROM appointments
WHERE finished_at IS NOT NULL
GROUP BY doctor_id, extract(year from scheduled_at), extract(month from scheduled_at)
答案 2 :(得分:0)
如果您的postgres版本是9.4或更高版本,则应考虑使用FILTER谓词,它比case语句更易读,性能更高。
SELECT doctor_id,
COUNT(*) AS total,
COUNT(*) FILTER (WHERE scheduled_at BETWEEN '2018-02-01' AND '2018-03-01') AS date_feb,
COUNT(*) FILTER (WHERE scheduled_at BETWEEN '2018-03-01' AND '2018-04-01') AS date_mar
FROM appointments
WHERE finished_at IS NOT NULL
GROUP BY doctor_id