Teradata - вычислить разницу между двумя датами из разных номеров строк - PullRequest
0 голосов
/ 08 января 2020

Я хочу перенести свои вычисления в Excel на Teradata, но не знаю, как это сделать. В Excel довольно легко, и я использую простой, если дать мне DIFF =IF(A2=A3, (C2-B3) * 24, "")

NO  T_DATE              L_DATE              DIFF
AAA 10/08/2019 17:02:00 10/08/2019 20:35:00 5.83
AAA 10/08/2019 14:45:00 10/08/2019 15:10:00 11.78
AAA 10/08/2019 03:23:00 10/08/2019 10:25:00 17.32
AAA 09/08/2019 17:06:00 10/08/2019 01:11:00 25.70
AAA 08/08/2019 23:29:00 09/08/2019 10:27:00 
BBB 08/08/2019 09:34:00 08/08/2019 21:19:00 22.23
BBB 07/08/2019 23:05:00 08/08/2019 06:09:00 18.03
BBB 07/08/2019 12:07:00 07/08/2019 20:25:00 22.32
BBB 06/08/2019 22:06:00 07/08/2019 08:53:00 22.77
BBB 06/08/2019 10:07:00 06/08/2019 19:44:00 

Есть ли способ сделать это в Teradata? Я хочу снова иметь разницу в часах между L_DATE и T_DATE для каждого NO.

1 Ответ

1 голос
/ 08 января 2020

Вы можете использовать оконные функции для достижения этой цели. Важно отметить, что когда вы вычитаете две даты или метки времени (в этом случае), вы будете возвращены в виде 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)
...