SQL Teradata - 添加第一行数据的列等有限制
SQL Teradata - Adding Column of first row data and so on w/ restrictions
目标: 获取 table 的当前行并找到该客户的最新项目并将该项目数据附加到下一列。如果最近的项目是该行的项目 1,那么它应该继续到下一行。逻辑应该始终位于该客户的第一行。订单基于交易日期并按客户 ID 分区。除了在 运行 脚本之后所需的结果集应该是什么样子之外,下面还提供了基础数据示例。
限制:我需要此脚本才能在 CRM 工具中运行。具体来说 Aprimo/CIM 由 teradata 提供。话虽如此,我不能使用 CTE (With) 或 volatile tables。由于 table 卷,我也不想在自身中创建多个连接。
到目前为止我所做的: 我觉得最好的方法可能是利用 Window 函数,但发现自己创建了很多嵌套的 case 语句.我真的很想知道是否有更好的方法来获得我正在寻找的答案。我可能不得不接受它并加入它自己。
Base table
Desired Result Set
快速入门基地Table:
CREATE VOLATILE TABLE Base
(
customer_id int
, trans_date date
, item varchar(1)
) ON COMMIT PRESERVE ROWS;
Insert Into Base (123,'2017-01-01','A');
Insert Into Base (123,'2017-01-02','B');
Insert Into Base (123,'2017-01-03','C');
Insert Into Base (123,'2017-01-04','D');
Insert Into Base (123,'2017-01-05','E');
Insert Into Base (999,'2017-01-06','F');
Insert Into Base (999,'2017-01-07','G');
Insert Into Base (999,'2017-01-08','H');
有一些 CASE,但不是 很多 :-)
SELECT
dt.*,
CASE
WHEN rn = 1
THEN Min(CASE WHEN rn = 2 THEN item end) Over (PARTITION BY customer_id)
ELSE Min(CASE WHEN rn = 1 THEN item end) Over (PARTITION BY customer_id)
END,
CASE
WHEN rn <=2
THEN Min(CASE WHEN rn = 3 THEN item end) Over (PARTITION BY customer_id)
ELSE Min(CASE WHEN rn = 2 THEN item end) Over (PARTITION BY customer_id)
END,
CASE
WHEN rn <= 3
THEN Min(CASE WHEN rn = 4 THEN item end) Over (PARTITION BY customer_id)
ELSE Min(CASE WHEN rn = 3 THEN item end) Over (PARTITION BY customer_id)
END
FROM
(
SELECT
Row_Number() Over (PARTITION BY customer_id ORDER BY trans_date) AS rn
,base.*
FROM Base
) AS dt
ORDER BY customer_id, trans_date
目标: 获取 table 的当前行并找到该客户的最新项目并将该项目数据附加到下一列。如果最近的项目是该行的项目 1,那么它应该继续到下一行。逻辑应该始终位于该客户的第一行。订单基于交易日期并按客户 ID 分区。除了在 运行 脚本之后所需的结果集应该是什么样子之外,下面还提供了基础数据示例。
限制:我需要此脚本才能在 CRM 工具中运行。具体来说 Aprimo/CIM 由 teradata 提供。话虽如此,我不能使用 CTE (With) 或 volatile tables。由于 table 卷,我也不想在自身中创建多个连接。
到目前为止我所做的: 我觉得最好的方法可能是利用 Window 函数,但发现自己创建了很多嵌套的 case 语句.我真的很想知道是否有更好的方法来获得我正在寻找的答案。我可能不得不接受它并加入它自己。
Base table
Desired Result Set
快速入门基地Table:
CREATE VOLATILE TABLE Base
(
customer_id int
, trans_date date
, item varchar(1)
) ON COMMIT PRESERVE ROWS;
Insert Into Base (123,'2017-01-01','A');
Insert Into Base (123,'2017-01-02','B');
Insert Into Base (123,'2017-01-03','C');
Insert Into Base (123,'2017-01-04','D');
Insert Into Base (123,'2017-01-05','E');
Insert Into Base (999,'2017-01-06','F');
Insert Into Base (999,'2017-01-07','G');
Insert Into Base (999,'2017-01-08','H');
有一些 CASE,但不是 很多 :-)
SELECT
dt.*,
CASE
WHEN rn = 1
THEN Min(CASE WHEN rn = 2 THEN item end) Over (PARTITION BY customer_id)
ELSE Min(CASE WHEN rn = 1 THEN item end) Over (PARTITION BY customer_id)
END,
CASE
WHEN rn <=2
THEN Min(CASE WHEN rn = 3 THEN item end) Over (PARTITION BY customer_id)
ELSE Min(CASE WHEN rn = 2 THEN item end) Over (PARTITION BY customer_id)
END,
CASE
WHEN rn <= 3
THEN Min(CASE WHEN rn = 4 THEN item end) Over (PARTITION BY customer_id)
ELSE Min(CASE WHEN rn = 3 THEN item end) Over (PARTITION BY customer_id)
END
FROM
(
SELECT
Row_Number() Over (PARTITION BY customer_id ORDER BY trans_date) AS rn
,base.*
FROM Base
) AS dt
ORDER BY customer_id, trans_date