Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Составление SQL-запросов > Нужна подсказка


Автор: Zzz 29.10.2020, 15:40
Добрый день, уважаемые форумчане!

Помогите составить запрос.

Есть таблица Table1 (пример)

Номер       Фамилия       Имя      Отчество       Дата
1             Иванов         Иван      Иванович      01.01.2000
1             Иванов         Иван      Иванович      02.01.2000
1             Акимов         Иван      Иванович      04.01.2000
2             Петров         Петр       Петрович      04.01.2000
2             Петров         Петр       Петрович      07.01.2000
3             Сидоров       Сидор     Сидорович    08.01.2000

В итоге нужно получить таблицу вида:

Номер      Фамилия        Имя     Отчество     Начало          Конец
1             Иванов          Иван     Иванович    01.01.2020    03.01.2000
1             Акимов          Иван     Иванович    04.01.2020    -
2             Петров          Петр      Петрович    04.01.2020    -
3             Сидоров        Сидор    Сидорович  08.01.2020    -

Объяснение: Поля Фамилия Имя Отчество могут меняться при одинаковом поле Номер. В итоговую таблицу в поле "Начало" должна попадать минимальная дата, в поле "Конец" - взять дату из строки изменения поля и вычесть 1 день. Если изменения полей не было - проставить null.

Набросок запроса:

Код

SELECT DISTINCT
            n,
            last_name,
            first_name,
            patronymic,
            min(date) over(partition by 
                n, 
                last_name, 
                first_name, 
                patronymic) as Nachalo,
                      ???
FROM Table 1


Понимаю, что скорее всего нужно использовать lead(), но сообразить не могу.

Синтаксис Oracle.



Автор: Akina 30.10.2020, 09:05
Вот как это выглядит в MySQL:

Код

WITH 
cte1 AS 
( SELECT Номер, 
         Фамилия, 
         Имя, 
         Отчество, 
         Дата,
         ROW_NUMBER() OVER (PARTITION BY Номер ORDER BY Дата) 
         - ROW_NUMBER() OVER (PARTITION BY Номер, Фамилия, Имя, Отчество ORDER BY Дата) grp
  FROM test ),
cte2 AS 
( SELECT Номер, Фамилия, Имя, Отчество, MIN(Дата) Начало, grp
  FROM cte1
  GROUP BY Номер, Фамилия, Имя, Отчество, grp )
SELECT *, LEAD(Начало) OVER (PARTITION BY Номер ORDER BY Начало) - INTERVAL 1 DAY Конец
FROM cte2
ORDER BY Номер, Начало

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=693c6693af0bdb9fffec2db13db168c9
В Оракле будет всё то же самое, возможно, кроме "минус 1 день". Ну и не забыть квотирование кириллических имён полей и алиасов.

Исходные данные я немного расширил для проверки возможных вариаций.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)