НЕОГРАНИЧЕННЫЕ СТРОКИ Teradata ПРЕДШЕСТВУЮЩИЕ

#teradata

#teradata

Вопрос:

У меня есть ниже набор данных со мной. Я хочу убедиться, что для любого конкретного идентификатора start_date, end_date и период между этими двумя датами не перекрываются с датами любого другого идентификатора.

 ID     Start_Date    End_Date
101    01-01-2001    31-01-2001
102    01-02-2001    28-02-2001
103    26-02-2001    31-03-2016
104    15-03-2001    30-04-2001
105    01-05-2002    31-05-2002
106    05-12-2002    31-12-2002
107    15-12-2002    05-01-2003 
  

Для этого я создал запрос ниже:

 select id,start_date,end_date,
case 
when 
end_date < max(end_date) over(order by start_date rows unbounded preceding)
then 'overlapping'
when 
start_date < max(end_date) over(order by start_date rows unbounded preceding)
then 'overlapping'
else 'non-overlapping'
end as FLAG from table
  

Я получаю нижеприведенный вывод, имеющий флаг all как «перекрывающийся», что неверно. Я думаю, что «строки, неограниченные предыдущими», также принимают текущую строку в вычислении:
Не могли бы вы сообщить мне, где я ошибаюсь:

 ID     Start_Date    End_Date    Flag
101    01-01-2001    31-01-2001  Overlapping
102    01-02-2001    28-02-2001  Overlapping
103    26-02-2001    31-03-2016  Overlapping
104    15-03-2001    30-04-2001  Overlapping
105    01-05-2002    31-05-2002  Overlapping
106    05-12-2002    31-12-2002  Overlapping
107    15-12-2002    05-01-2003  Overlapping
  

Комментарии:

1. Конечно rows unbounded preceding , включает текущую строку, это ярлык для rows between unbounded preceding and current row . Можете ли вы показать, какой точный результат должен быть возвращен?

2. вы уверены, что ID103 относится к 2016, а не к 2001?

Ответ №1:

Для этого есть несколько способов. Поскольку перекрытие диапазонов дат может быть сложным, я бы использовал логику периодов Teradata и самосоединение:

 SELECT
    *
FROM
    table t1
    INNER JOIN table t2 ON
        period(t1.start_date, next(t1.end_date)) P_INTERSECT period(t2.start_date, next(t2.end_date)) IS NOT NULL
  

Это преобразует ваши даты начала и окончания в тип данных ПЕРИОДА, а затем выполняет поиск записей с пересекающимися периодами. Результатами будут две записи, объединенные в одну запись, где происходит перекрытие.

Ответ №2:

Вы также можете попробовать это старомодным способом, например:

 CREATE TABLE db.t 
  (id INT,
  start_date DATE,
  end_date DATE);
INSERT INTO db.t VALUES (101,'2001-01-01','2001-01-31');
INSERT INTO db.t VALUES (102,'2001-02-01','2001-02-28');
INSERT INTO db.t VALUES (103,'2001-02-26','2001-03-31');
INSERT INTO db.t VALUES (104,'2001-03-15','2001-04-30');
INSERT INTO db.t VALUES (105,'2002-05-01','2002-05-31');
INSERT INTO db.t VALUES (106,'2002-12-05','2002-12-31');
INSERT INTO db.t VALUES (107,'2002-12-01','2003-01-05');
SELECT 
  t.id,
  t.start_date,
  t.end_date,
  MAX(CASE WHEN o.id IS NULL THEN 'non-overlapping'
  ELSE 'overlaps with' || o.id END) AS flag
FROM
  db.t t LEFT OUTER JOIN
  db.t o ON
  t.start_date < o.end_date AND
  t.end_date >= o.start_date AND
  t.id <> o.id
GROUP BY 1,2,3
  

возвращает (сортируется вручную)

 id  start_date  end_date    flag
101 01/01/2001  01/31/2001  non-overlapping
102 02/01/2001  02/28/2001  overlaps with        103
103 02/26/2001  03/31/2001  overlaps with        104
104 03/15/2001  04/30/2001  overlaps with        103
105 05/01/2002  05/31/2002  non-overlapping
106 12/05/2002  12/31/2002  overlaps with        107
107 12/01/2002  01/05/2003  overlaps with        106