Запрос перекрывающихся диапазонов дат в одной и той же таблице SQL - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть таблица в базе данных Oracle oracle.

Ее столбцами являются VEHICLE_ID, GEAR_ID, STARTDATE, ENDDATE, AA.

Начальная дата и конечная дата представляют диапазон дат в шестерёнкеактивен для конкретного транспортного средства.

Моя проблема в том, что мне нужно найти те же шестерни того же транспортного средства, которые имеют перекрывающиеся даты.

Я пришел с этим запросом

SELECT DISTINCT G.* FROM VEHICLE_GEARS G JOIN (SELECT A.*, B.CNT FROM VEHICLE_GEARS A JOIN
(SELECT VEHICLE_ID, GEAR_ID, COUNT(GEAR_ID) CNT FROM VEHICLE_GEARS GROUP BY 

VEHICLE_ID, GEAR_ID HAVING COUNT(GEAR_ID) > 1) B
    ON A.VEHICLE_ID = B.VEHICLE_ID AND A.GEAR_ID = B.GEAR_ID) ASDF ON
    G.VEHICLE_ID = ASDF.VEHICLE_ID AND G.GEAR_ID = ASDF.GEAR_ID
WHERE 
    NOT(
        TRUNC(ASDF.STARTDATE) >= TRUNC(G.ENDDATE)
        OR
        TRUNC(ASDF.ENDDATE) <= TRUNC(G.STARTDATE)
        )
    ORDER BY 1, 5

Проблема заключается в том, что при этом учитывается перекрытие даже дат, имеющих одинаковую конечную дату передачи, с начальной датой передачи, которую я не хочу, но даже после удаления равенства из предложений where результаты совпадают.

Пожалуйста, помогите, заранее спасибо.

РЕДАКТИРОВАТЬ: Пример данных (после запроса выше):

000000006   2012-02-20 00:00:00 3   2999-12-31 00:00:00 804
000000006   1991-07-01 00:00:00 9   2999-12-31 00:00:00 804
000000147   1991-07-01 00:00:00 1   1992-10-08 00:00:00 601
000000147   1992-10-08 00:00:00 2   2999-12-31 00:00:00 601

Ожидается, что транспортное средство 000000147 не должно быть в наборе результатовпотому что конечная дата шестерни 601 такая же, как и у ее второго «экземпляра».Первые две записи (автомобиль 00000006) являются правильными, поскольку даты передачи 804 перекрываются.

ОБРАЗЕЦ ДАННЫХ ТАБЛИЦ:

000000000   2014-02-25 00:00:00 1   2999-12-31 00:00:00 302
000000000   2006-12-15 00:00:00 3   2999-12-31 00:00:00 604
000000000   2006-12-15 00:00:00 4   2999-12-31 00:00:00 605
000000006   1991-07-01 00:00:00 1   2999-12-31 00:00:00 601
000000006   2016-01-18 00:00:00 10  2999-12-31 00:00:00 605
000000006   2012-02-20 00:00:00 3   2999-12-31 00:00:00 804
000000006   1991-07-01 00:00:00 9   2999-12-31 00:00:00 804
000000147   1991-07-01 00:00:00 1   1992-10-08 00:00:00 601
000000147   1992-10-08 00:00:00 2   2999-12-31 00:00:00 601

ОЖИДАЕМЫЕ РЕЗУЛЬТАТЫ:

000000000   2006-12-15 00:00:00 4   2999-12-31 00:00:00 605
000000006   2016-01-18 00:00:00 10  2999-12-31 00:00:00 605

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Вы можете использовать аналитические функции LAG и LEAD, и вам не нужно использовать самостоятельные объединения:

Установка Oracle :

CREATE TABLE VEHICLE_GEARS ( vehicle_id, startdate, enddate, gear_id ) AS
SELECT '000000000', DATE '2014-02-25', DATE '2999-12-31', 302 FROM DUAL UNION ALL -- No duplicate vehicle & gear
SELECT '000000000', DATE '2006-12-15', DATE '2999-12-31', 604 FROM DUAL UNION ALL -- No duplicate vehicle & gear
SELECT '000000000', DATE '2006-12-15', DATE '2999-12-31', 605 FROM DUAL UNION ALL -- No duplicate vehicle & gear
SELECT '000000006', DATE '1991-07-01', DATE '2999-12-31', 601 FROM DUAL UNION ALL -- No duplicate vehicle & gear
SELECT '000000006', DATE '2016-01-18', DATE '2999-12-31', 605 FROM DUAL UNION ALL -- No duplicate vehicle & gear
SELECT '000000006', DATE '2012-02-20', DATE '2999-12-31', 804 FROM DUAL UNION ALL -- Overlaps previous
SELECT '000000006', DATE '1991-07-01', DATE '2999-12-31', 804 FROM DUAL UNION ALL -- Overlaps next
SELECT '000000147', DATE '1991-07-01', DATE '1992-10-08', 601 FROM DUAL UNION ALL -- Same end date as next start date
SELECT '000000147', DATE '1992-10-08', DATE '2999-12-31', 601 FROM DUAL UNION ALL -- Same start date as previous end date
SELECT '000000567', DATE '2018-01-01', DATE '2018-12-31', 203 FROM DUAL UNION ALL -- Overlaps next
SELECT '000000567', DATE '2018-12-01', DATE '2019-01-10', 203 FROM DUAL UNION ALL -- Overlaps previous and next
SELECT '000000567', DATE '2018-12-31', DATE '2019-01-10', 203 FROM DUAL UNION ALL -- Overlaps previous and next
SELECT '000000567', DATE '2018-12-31', DATE '2019-01-31', 203 FROM DUAL UNION ALL -- Overlaps previous
SELECT '000000567', DATE '2019-01-31', DATE '2019-02-28', 203 FROM DUAL           -- Same start date as previous

Запрос :

SELECT vehicle_id,
       startdate,
       enddate,
       gear_id
FROM   (
  SELECT G.*,
         LAG( enddate   ) OVER ( PARTITION BY vehicle_id, gear_id ORDER BY startdate, enddate ) AS prev_enddate,
         LEAD( startdate ) OVER ( PARTITION BY vehicle_id, gear_id ORDER BY startdate, enddate ) AS next_startdate
  FROM   VEHICLE_GEARS G
)
WHERE  prev_enddate > startdate
AND    ( enddate <= next_startdate OR next_startdate IS NULL );

Вывод :

VEHICLE_ID | STARTDATE | ENDDATE   | GEAR_ID
:--------- | :-------- | :-------- | ------:
000000006  | 20-FEB-12 | 31-DEC-99 |     804
000000567  | 31-DEC-18 | 31-JAN-19 |     203

дБ <> скрипка здесь

0 голосов
/ 14 февраля 2019

В простейшем виде это дает все в таблице, которая начинается до того, как заканчивается другая строка, где снаряжение и транспортное средство совпадают, используя простое самостоятельное соединение:

select t1.*, t2.*
from VEHICLE_GEARS t1
inner join VEHICLE_GEARS t2
  on t1.gear_id = t2.gear_id
  and t1.vehicle_id = t2.vehicle_id
  and t2.startdate < t1.enddate
  and t1.startdate < t2.startdate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...