Снимок экземпляра строки таблицы с временными интервалами


2 принят

Вы можете быстро выполнить эту работу с типом данных Teradata PERIOD. Период - это диапазон дат или временных меток. В качестве аргументов требуется две даты или временные метки: первая для даты начала и вторая для даты окончания (до, но не включая).

В вашем случае мы преобразуем ваши End_Dateи P_INTERSECTв периоды, чтобы выполнить соединение. Мы будем использовать функцию Period, чтобы найти перекрывающиеся периоды, к которым мы присоединяемся.SELECT attr1, attr2, /*pull the BEGIN of the intersected period*/ BEGIN(t1.validperiod P_INTERSECT t2.validperiod) as startdate, /*pull the END of the intersected period (subtracting a day since period end dates are "up to but not including")*/ PRIOR(END(t1.validperiod P_INTERSECT t2.validperiod)) as enddate FROM (SELECT abc.*, PERIOD(start_date, NEXT(end_date)) as validperiod FROM abc) t1 INNER JOIN (SELECT pqr.*, PERIOD(start_Date, NEXT(end_date)) as validperiod FROM pqr) t2 ON t1.id = t2.id /* * Now P_INTERSECT our two periods and look for Non-Null intersections * The intersection is the date range where the two periods overlap */ AND t1.validperiod P_INTERSECT t2.validperiod IS NOT NULL;

t1.validperiod P_INTERSECT t2.validperiod P_INTERSECT t3.validperiod IS NOT NULL

Есть несколько бонусов, которые мы получаем здесь:

  1. Логика чиста и проста. Нет тестов для max (start_date) и min (end_date) с вложенными операциями CASE и всем этим ужасом
  2. Если вам нужно присоединиться к третьей таблице, просто преобразуйте ее начальную и конечную дату в validperiod и присоединитесь к Simple simple.create table abc ( id integer, attr1 varchar(3), start_date date, end_date date) PRIMARY INDEX(ID); create table PQR ( id integer, attr2 varchar(3), start_date date, end_date date) PRIMARY INDEX(ID); INSERT INTO abc VALUES(1,'LMN','2017-01-01','2017-02-28'); INSERT INTO abc VALUES(1,'HGI','2017-02-28','2017-03-15'); INSERT INTO abc VALUES(1,'STI','2017-03-15','2099-12-31'); INSERT INTO PQR VALUES(1,'KLM','2017-01-01','2017-01-20'); INSERT INTO PQR VALUES(1,'TLF','2017-01-20','2017-04-04'); INSERT INTO PQR VALUES(1,'SNQ','2017-04-04','2099-12-31'); select a.id,a.attr1,p.attr2, cast(greatest(cast(a.start_date as int),cast(p.start_date as int)) as date)start_date, cast(least(cast(a.end_date as int),cast(p.end_date as int)) as date)end_date from abc a inner join pqr p on a.id=p.id where a.start_date between p.start_date and p.end_date or a.end_date between p.start_date and p.end_date order by 4;
  3. Есть несколько других действительно полезных функций, которые основаны на сроках, что сделает эту работу быстрой. Например, NORMALIZE объединяет несколько записей на основе составного ключа и перекрытия и периодов встреч.

Наконец, как правило, когда я создаю таблицы, и эта таблица имеет дату начала и дату окончания, я ВСЕГДА создаю новое поле с именем validperiod и загружаю его, как мы делаем в этих подзапросах. Тогда вам не нужно конвертировать в период, чтобы ваши объединения были дружелюбны. Просто возьмите уже сохраненный столбец validperiod и запустите P_INTERSECTing. Он принимает всю работу из других уродливых объединений и выбирает.


0

Нет сложного алгоритма. Простой sql с функцией cross-join, между и наибольшей / наименьшей функцией.

    id  attr1   attr2   start_date  end_date
1   1   LMN KLM 1/1/2017    1/20/2017
2   1   LMN TLF 1/20/2017   2/28/2017
3   1   HGI TLF 2/28/2017   3/15/2017
4   1   STI TLF 3/15/2017   4/4/2017
5   1   STI SNQ 4/4/2017    12/31/2099

ВЫВОД:

Единственное различие в том, что я взял 2099 вместо 1999, чтобы упростить задачу. вы также можете использовать 1999 год и настроить этот запрос (не рекомендуется).

SQL, аналитика, Teradata, данные-склад, оконные функции,

sql,analytics,teradata,data-warehouse,window-functions,

2

Ответов: 2


2 принят

Вы можете быстро выполнить эту работу с типом данных Teradata PERIOD. Период - это диапазон дат или временных меток. В качестве аргументов требуется две даты или временные метки: первая для даты начала и вторая для даты окончания (до, но не включая).

В вашем случае мы преобразуем ваши End_Dateи P_INTERSECTв периоды, чтобы выполнить соединение. Мы будем использовать функцию Period, чтобы найти перекрывающиеся периоды, к которым мы присоединяемся.SELECT attr1, attr2, /*pull the BEGIN of the intersected period*/ BEGIN(t1.validperiod P_INTERSECT t2.validperiod) as startdate, /*pull the END of the intersected period (subtracting a day since period end dates are "up to but not including")*/ PRIOR(END(t1.validperiod P_INTERSECT t2.validperiod)) as enddate FROM (SELECT abc.*, PERIOD(start_date, NEXT(end_date)) as validperiod FROM abc) t1 INNER JOIN (SELECT pqr.*, PERIOD(start_Date, NEXT(end_date)) as validperiod FROM pqr) t2 ON t1.id = t2.id /* * Now P_INTERSECT our two periods and look for Non-Null intersections * The intersection is the date range where the two periods overlap */ AND t1.validperiod P_INTERSECT t2.validperiod IS NOT NULL;

t1.validperiod P_INTERSECT t2.validperiod P_INTERSECT t3.validperiod IS NOT NULL

Есть несколько бонусов, которые мы получаем здесь:

  1. Логика чиста и проста. Нет тестов для max (start_date) и min (end_date) с вложенными операциями CASE и всем этим ужасом
  2. Если вам нужно присоединиться к третьей таблице, просто преобразуйте ее начальную и конечную дату в validperiod и присоединитесь к Simple simple.create table abc ( id integer, attr1 varchar(3), start_date date, end_date date) PRIMARY INDEX(ID); create table PQR ( id integer, attr2 varchar(3), start_date date, end_date date) PRIMARY INDEX(ID); INSERT INTO abc VALUES(1,'LMN','2017-01-01','2017-02-28'); INSERT INTO abc VALUES(1,'HGI','2017-02-28','2017-03-15'); INSERT INTO abc VALUES(1,'STI','2017-03-15','2099-12-31'); INSERT INTO PQR VALUES(1,'KLM','2017-01-01','2017-01-20'); INSERT INTO PQR VALUES(1,'TLF','2017-01-20','2017-04-04'); INSERT INTO PQR VALUES(1,'SNQ','2017-04-04','2099-12-31'); select a.id,a.attr1,p.attr2, cast(greatest(cast(a.start_date as int),cast(p.start_date as int)) as date)start_date, cast(least(cast(a.end_date as int),cast(p.end_date as int)) as date)end_date from abc a inner join pqr p on a.id=p.id where a.start_date between p.start_date and p.end_date or a.end_date between p.start_date and p.end_date order by 4;
  3. Есть несколько других действительно полезных функций, которые основаны на сроках, что сделает эту работу быстрой. Например, NORMALIZE объединяет несколько записей на основе составного ключа и перекрытия и периодов встреч.

Наконец, как правило, когда я создаю таблицы, и эта таблица имеет дату начала и дату окончания, я ВСЕГДА создаю новое поле с именем validperiod и загружаю его, как мы делаем в этих подзапросах. Тогда вам не нужно конвертировать в период, чтобы ваши объединения были дружелюбны. Просто возьмите уже сохраненный столбец validperiod и запустите P_INTERSECTing. Он принимает всю работу из других уродливых объединений и выбирает.


0

Нет сложного алгоритма. Простой sql с функцией cross-join, между и наибольшей / наименьшей функцией.

    id  attr1   attr2   start_date  end_date
1   1   LMN KLM 1/1/2017    1/20/2017
2   1   LMN TLF 1/20/2017   2/28/2017
3   1   HGI TLF 2/28/2017   3/15/2017
4   1   STI TLF 3/15/2017   4/4/2017
5   1   STI SNQ 4/4/2017    12/31/2099

ВЫВОД:

Единственное различие в том, что я взял 2099 вместо 1999, чтобы упростить задачу. вы также можете использовать 1999 год и настроить этот запрос (не рекомендуется).

SQL, аналитика, Teradata, данные-склад, оконные функции,
Похожие вопросы