powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Вопрос по GROUP BY
6 сообщений из 6, страница 1 из 1
Вопрос по GROUP BY
    #39846170
Explosion
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Стоит задача вытащить все записи приёмов у врача людей в возрасте 18+, 65 лет мужчины, 65 лет женщины, >65 лет мужчины, >65 лет женщины по заданному периоду времени.
Мой запрос выглядит так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT
  CASE
    when extract(year from current_date) - extract(year from e.dr) = 65 then 'Мужчины в возрасте 65 лет'
    when extract(year from current_date) - extract(year from e.dr) > 65 then 'Мужчины в возрасте старше 65 лет'
    when extract(year from current_date) - extract(year from e.dr) = 65 then 'Женщины в возрасте 65 лет'
    when extract(year from current_date) - extract(year from e.dr) > 65 then 'Женщины в возрасте старше 65 лет'
    when extract(year from current_date) - extract(year from e.dr) >= 18 then 'Всего взрослых (в возрасте 18 лет и старше)'
  END "Группы",
  e.sex "Пол",
  count (case when i.year_period = 2019 then i.id end) "Подлежат диспансерному наблюдению в отчетном году, человек"
  count (case when i.year_period = 2019 and d.m >= 1 and d.m <= 6 then i.id end) "Из них: в отчетном периоде"
FROM www_insured i
JOIN erz e ON e.id = i.erz_id
JOIN www_dn_info d ON i.id = d.insured_id
WHERE i.screening_type = 4
GROUP BY 1,2


Где таблица www_insured содежит людей, а таблица www_dn_info содержит приёмы у врача данных людей.
Group by работает по следующему принципу: Так как люди в возрасте 65 лет и люди возрастом больше 65 лет входят в множество >18 лет, то из общего количества >18 лет почему-то вычитаются результаты других групп возрастов.
Как написать запрос так, чтобы при группировки цифры соответствовали реальному количеству людей 18+.

P.S. Кстати, если в CASE строчку "when extract(year from current_date) - extract(year from e.dr) >= 18 then 'Всего взрослых (в возрасте 18 лет и старше)", то остальная группа возрастов показываться не будет.

Решил вопрос запросом такого вида:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
SELECT Vozrast "Группы", count(Vozrast) as "Подлежат диспансерному наблюдению в отчетном году, человек"
FROM (
      SELECT 'Всего взрослых (в возрасте 18 лет и старше)' as Vozrast
      FROM www_insured i
      JOIN erz e ON e.id = i.erz_id
      JOIN www_dn_info d ON i.id = d.insured_id
      WHERE i.screening_type = 4
      AND i.year_period = 2019
      AND extract(year from current_date) - extract(year from e.dr) >= 18

      UNION ALL

      SELECT 'Мужчины в возрасте 65 лет'
      FROM www_insured i
      JOIN erz e ON e.id = i.erz_id
      JOIN www_dn_info d ON i.id = d.insured_id
      WHERE i.screening_type = 4
      AND i.year_period = 2019
      AND extract(year from current_date) - extract(year from e.dr) = 65 and (e.sex = 'М' or e.sex = 'M')

      UNION ALL

      SELECT 'Мужчины в возрасте старше 65 лет'
      FROM www_insured i
      JOIN erz e ON e.id = i.erz_id
      JOIN www_dn_info d ON i.id = d.insured_id
      WHERE i.screening_type = 4
      AND i.year_period = 2019
      AND extract(year from current_date) - extract(year from e.dr) > 65 and (e.sex = 'М' or e.sex = 'M')

      UNION ALL

      SELECT 'Женщины в возрасте 65 лет'
      FROM www_insured i
      JOIN erz e ON e.id = i.erz_id
      JOIN www_dn_info d ON i.id = d.insured_id
      WHERE i.screening_type = 4
      AND i.year_period = 2019
      AND extract(year from current_date) - extract(year from e.dr) = 65 and e.sex = 'Ж'

      UNION ALL

      SELECT 'Женщины в возрасте старше 65 лет'
      FROM www_insured i
      JOIN erz e ON e.id = i.erz_id
      JOIN www_dn_info d ON i.id = d.insured_id
      WHERE i.screening_type = 4
      AND i.year_period = 2019
      AND extract(year from current_date) - extract(year from e.dr) > 65 and e.sex = 'Ж'

      ) as T

GROUP BY Vozrast


В этом случае цифры соответствуют действительности. Но он выполняется соответственно в 5 раз дольше. И довольно не гибкий при дальнейшей работе с ним.
Ну и вопрос. Посоветуйте можно ли как-то модернизировать первый запрос, чтобы цифры соответствовали действительности. Или есть ли альтернативные пути решения.
...
Рейтинг: 0 / 0
Вопрос по GROUP BY
    #39846179
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Explosion,

зачем в названиях групп указывать пол, если вы его выводите отдельным полем и ещё группируете?
Я бы в ваших группах сразу добавил условие фильтрации по полу, и убрал его вывод в качестве отдельного столбца

Ну и i.year_period = 2019 засунул в where
...
Рейтинг: 0 / 0
Вопрос по GROUP BY
    #39846184
Explosion
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не до конца отредактировал для поста. В моих реалиях больше условий и полей. И может быть ситуация, когда появится необходимость вывести 65+ людей для другого года или месяца. Поэтому условия прописаны в select.
В общем по вашему способу отредактировал (один фиг на правильность не повлияет):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT
  CASE
    when extract(year from current_date) - extract(year from e.dr) = 65 and e.sex = 'М' then 'Мужчины в возрасте 65 лет'
    when extract(year from current_date) - extract(year from e.dr) > 65 and e.sex = 'М' then 'Мужчины в возрасте старше 65 лет'
    when extract(year from current_date) - extract(year from e.dr) = 65 and e.sex = 'Ж' then 'Женщины в возрасте 65 лет'
    when extract(year from current_date) - extract(year from e.dr) > 65 and e.sex = 'М' then 'Женщины в возрасте старше 65 лет'
    when extract(year from current_date) - extract(year from e.dr) >= 18 then 'Всего взрослых (в возрасте 18 лет и старше)'
  END "Группы",
  count (i.id) "Подлежат диспансерному наблюдению в отчетном году, человек"
FROM www_insured i
JOIN erz e ON e.id = i.erz_id
JOIN www_dn_info d ON i.id = d.insured_id
WHERE i.year_period = 2019
AND d.m >=1 AND d.m <=6
GROUP BY 1
...
Рейтинг: 0 / 0
Вопрос по GROUP BY
    #39846194
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Explosion,

тьфу блин неверно посмотрел на ваш запрос. Видать не проснулся ещё.
Конечно же он не верно работает. Всего взрослых (в возрасте 18 лет и старше) надо считать отдельно. Грубо говоря делайте отдельный запрос по учёту групп разбитых по возрастным не пересекающимся категориям, а потом объединяйте его UNION ALL с запросом который считает для старше 18 лет
...
Рейтинг: 0 / 0
Вопрос по GROUP BY
    #39846198
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Explosion,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
SELECT
  CASE
    when extract(year from current_date) - extract(year from e.dr) = 65  and e.sex = 'М' then 'Мужчины в возрасте 65 лет'
    when extract(year from current_date) - extract(year from e.dr) > 65  and e.sex = 'М' then 'Мужчины в возрасте старше 65 лет'
    when extract(year from current_date) - extract(year from e.dr) = 65  and e.sex = 'Ж' then 'Женщины в возрасте 65 лет'
    when extract(year from current_date) - extract(year from e.dr) > 65  and e.sex = 'Ж' then 'Женщины в возрасте старше 65 лет'
  END "Группы",
  count (case when i.year_period = 2019 then i.id end) "Подлежат диспансерному наблюдению в отчетном году, человек"
  count (case when i.year_period = 2019 and d.m >= 1 and d.m <= 6 then i.id end) "Из них: в отчетном периоде"
FROM www_insured i
JOIN erz e ON e.id = i.erz_id
JOIN www_dn_info d ON i.id = d.insured_id
WHERE i.screening_type = 4
  AND extract(year from current_date) - extract(year from e.dr) >= 65
GROUP BY 1
UNION ALL
SELECT
  'Всего взрослых (в возрасте 18 лет и старше)' AS "Группы",
  count (case when i.year_period = 2019 then i.id end) "Подлежат диспансерному наблюдению в отчетном году, человек"
  count (case when i.year_period = 2019 and d.m >= 1 and d.m <= 6 then i.id end) "Из них: в отчетном периоде"
FROM www_insured i
JOIN erz e ON e.id = i.erz_id
JOIN www_dn_info d ON i.id = d.insured_id
WHERE i.screening_type = 4
  AND extract(year from current_date) - extract(year from e.dr) >= 18
GROUP BY 1



будет медленней всего в 2 раза, а не в 5
...
Рейтинг: 0 / 0
Вопрос по GROUP BY
    #39846221
Explosion
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Денис, спасибо.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Вопрос по GROUP BY
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]