GROUP BY foreign_key и диапазон дат - PullRequest
0 голосов
/ 14 декабря 2018

Я работаю с таблицей с именем appointments, столбцы которой:

schedule_at: datetime doctor_id: целочисленное описание: текст done_at: datetime

Я хочу получить COUNT для всехвстречи, которые закончились, сгруппированы по doctor_id, а также сгруппированы по набору интервалов дат, которые варьируются в зависимости от заданного набора входных данных.Входные данные, которые я получаю: from, который является датой, и to, который также является датой.

Первый вариант использования, который я хочу решить, - это разделение результатов по месяцам от заданного from иto.Итак, если мне дают from = '2018-02-03' и to = '2018-10-03', я хочу получить СЧЕТ всех назначений, которые закончились для каждого врача И за каждый месяц с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, поэтому мне просто нужно сделатьодин запрос.

Ответы [ 3 ]

0 голосов
/ 14 декабря 2018

Используйте 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)
0 голосов
/ 14 декабря 2018

Если ваша версия 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
0 голосов
/ 14 декабря 2018

Вы можете использовать условное агрегирование:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...