рассчитывать на человека по месяцу между днями в mysql - PullRequest
1 голос
/ 13 марта 2020

У меня есть таблица отсутствий с 3 столбцами id, begin_dt, end_dt. Мне нужно подсчитать, сколько идентификаторов имеет хотя бы один день отсутствия в этом месяце. Так, например, есть следующая строка:

id  begin_dt    end_dt
1   01/01/2020  02/02/2020
2   02/02/2020  02/02/2020

мой результат должен быть

month   count
01-2020 1
02-2020 2

Я думал с группой на DATE_FORMAT (SYSDATE (), '% Y- % m '), но я не знаю, как справиться с тем фактом, что нам пришлось искать весь период begin_dt до end_dt

. Рабочее создание таблицы этого примера можно найти здесь: https://www.db-fiddle.com/f/rYBsxQzTjjQ9nGBEmeAX6W/0 Схема (MySQL v5.7)

CREATE TABLE absence (
  `id` VARCHAR(6),
  `begin_dt` DATETIME,
  `end_dt` DATETIME
);

INSERT INTO absence
  (`id`, `begin_dt`, `end_dt`)
VALUES
  ('1', DATE('2019-01-01'), DATE('2019-02-02')),
  ('2', DATE('2019-02-02'), DATE('2019-02-02'));

Запрос # 1

    select * from absence;

| id  | begin_dt            | end_dt              |
| --- | ------------------- | ------------------- |
| 1   | 2019-01-01 00:00:00 | 2019-02-02 00:00:00 |
| 2   | 2019-02-02 00:00:00 | 2019-02-02 00:00:00 |

Посмотреть на скрипку БД

1 Ответ

1 голос
/ 13 марта 2020
SELECT DATE_FORMAT(startofmonth, '%Y-%m-01') year_and_month,
       COUNT(*) absent_person_count
FROM absence
JOIN ( SELECT DATE_FORMAT(dt + INTERVAL n MONTH, '%Y-%m-01') startofmonth,
              DATE_FORMAT(dt + INTERVAL n MONTH, '%Y-%m-01') + INTERVAL 1 MONTH - INTERVAL 1 DAY endofmonth
       FROM ( SELECT MIN(begin_dt) dt
              FROM absence ) startdate,
            ( SELECT 0 n UNION ALL 
              SELECT 1 UNION ALL 
              SELECT 2 UNION ALL 
              SELECT 3 UNION ALL 
              SELECT 4 UNION ALL 
              SELECT 5 ) numbers,
            ( SELECT DATE_FORMAT(MIN(begin_dt), '%Y-%m') mindate, 
                     DATE_FORMAT(MAX(end_dt), '%Y-%m') maxdate 
              FROM absence ) datesrange
       WHERE DATE_FORMAT(dt + INTERVAL n MONTH, '%Y-%m') BETWEEN mindate AND maxdate ) dateslist
    ON  begin_dt <= endofmonth
    AND end_dt >= startofmonth
GROUP BY year_and_month;

скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...