Вы можете использовать оконные функции для достижения этой цели. Важно отметить, что когда вы вычитаете две даты или метки времени (в этом случае), вы будете возвращены в виде INTERVAL
, поэтому вам нужно будет указать, какой тип ИНТЕРВАЛА вы хотите, а также его размер (SECOND, MINUTE, HOUR, ДЕНЬ и т. Д. c) ..
CREATE MULTISET VOLATILE TABLE yourtable(
ID VARCHAR(3)
,T_DATE TIMESTAMP(0)
,L_DATE TIMESTAMP(0)
,DIFF NUMERIC(6,2)
) PRIMARY INDEX (ID) ON COMMIT PRESERVE ROWS;
INSERT INTO yourtable(ID,T_DATE,L_DATE,DIFF) VALUES ('AAA','2019-10-08 17:02:00','2019-10-08 20:35:00',5.83);
INSERT INTO yourtable(ID,T_DATE,L_DATE,DIFF) VALUES ('AAA','2019-10-08 14:45:00','2019-10-08 15:10:00',11.78);
INSERT INTO yourtable(ID,T_DATE,L_DATE,DIFF) VALUES ('AAA','2019-10-08 03:23:00','2019-10-08 10:25:00',17.32);
INSERT INTO yourtable(ID,T_DATE,L_DATE,DIFF) VALUES ('AAA','2019-09-08 17:06:00','2019-10-08 01:11:00',25.70);
INSERT INTO yourtable(ID,T_DATE,L_DATE,DIFF) VALUES ('AAA','2019-08-08 23:29:00','2019-09-08 10:27:00',NULL);
INSERT INTO yourtable(ID,T_DATE,L_DATE,DIFF) VALUES ('BBB','2019-08-08 09:34:00','2019-08-08 21:19:00',22.23);
INSERT INTO yourtable(ID,T_DATE,L_DATE,DIFF) VALUES ('BBB','2019-07-08 23:05:00','2019-08-08 06:09:00',18.03);
INSERT INTO yourtable(ID,T_DATE,L_DATE,DIFF) VALUES ('BBB','2019-07-08 12:07:00','2019-07-08 20:25:00',22.32);
INSERT INTO yourtable(ID,T_DATE,L_DATE,DIFF) VALUES ('BBB','2019-06-08 22:06:00','2019-07-08 08:53:00',22.77);
INSERT INTO yourtable(ID,T_DATE,L_DATE,DIFF) VALUES ('BBB','2019-06-08 10:07:00','2019-06-08 19:44:00',NULL);
SELECT yourtable.*,
CAST(((LEAD(T_DATE) OVER (PARTITION BY ID ORDER BY T_DATE) - L_DATE) HOUR(4)) AS INTEGER)
FROM yourtable;
+-----+---------------------+---------------------+--------+-------------------------------------------+
| ID | T_DATE | L_DATE | DIFF | (LEAD (<value expression>) - L_DATE) HOUR |
+-----+---------------------+---------------------+--------+-------------------------------------------+
| AAA | 2019-08-08 23:29:00 | 2019-09-08 10:27:00 | <null> | 7 |
| AAA | 2019-09-08 17:06:00 | 2019-10-08 01:11:00 | 25.70 | 2 |
| AAA | 2019-10-08 03:23:00 | 2019-10-08 10:25:00 | 17.32 | 4 |
| AAA | 2019-10-08 14:45:00 | 2019-10-08 15:10:00 | 11.78 | 2 |
| AAA | 2019-10-08 17:02:00 | 2019-10-08 20:35:00 | 5.83 | <null> |
| BBB | 2019-06-08 10:07:00 | 2019-06-08 19:44:00 | <null> | 3 |
| BBB | 2019-06-08 22:06:00 | 2019-07-08 08:53:00 | 22.77 | 4 |
| BBB | 2019-07-08 12:07:00 | 2019-07-08 20:25:00 | 22.32 | 3 |
| BBB | 2019-07-08 23:05:00 | 2019-08-08 06:09:00 | 18.03 | 3 |
| BBB | 2019-08-08 09:34:00 | 2019-08-08 21:19:00 | 22.23 | <null> |
+-----+---------------------+---------------------+--------+-------------------------------------------+
Причина, по которой это выглядит так некрасиво, заключается в том, что вы пытаетесь сравнить (вычесть) значения в двух разных записях. В базе данных нет связи между одной записью и другой. Там нет заказа. Они живут независимо друг от друга. Это радикально отличается от Excel, где строки (записи) имеют порядок (номер строки).
Мы используем оконную функцию LEAD()
, чтобы установить sh группу записей как группу (раздел), используя предложение PARTITION BY
, и мы даем этому разделу порядок с ORDER BY
пункт. Затем мы используем это LEAD()
, чтобы сказать: «Следующее T_DATE
в этом упорядоченном разделе для этой записи».
Затем мы вычисляем дату и вычитаем две метки времени. Мы указываем, что мы хотим вернуть INTERVAL
типа HOUR(4)
. Это будет продолжаться до 9999 часов, и это будет ошибка, если он пройдет более 9999 часов.
Наконец, мы приводим эту вещь к целому числу, чтобы вы могли делать математические вычисления. Вы не должны, однако, делать кастинг, если вы не хотите. Я добавил это, потому что часто мы хотим добавить часы вместе и еще много чего.
Если вы работаете с более старой версией Teradata, у которой нет функции LEAD()
(это более новое дополнение), вы можете использовать MAX()
или MIN()
и некоторый дополнительный синтаксис в ваше определение окна, чтобы точно сказать "Просто T_DATE следующей записи", как:
MAX(T_DATE) OVER (PARTITION BY ID ORDER BY T_DATE ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)