[英]How to insert a row in the middle of a slowly changing dimension type 2 based on a date value
我需要在 SCD-2 表中插入一条记录。 我们使用的数据库是 Oracle 12C。 情况如下 - SCD2 表中的当前记录集 -
Prod_Id Begin_Version_dt End_version_dt
'1234', '2020-03-10', '2020-04-09'
'1234', '2020-04-10', '2020-05-10'
'1234', '2020-05-11', '9999-12-31'
Prod 事务表中有一条记录如下 -
Prod_Id Trans_dt
'1234', '2020-05-15'
SCD2 中的更新记录集应该是 -
Prod_Id Begin_Version_dt End_version_dt
'1234', '2020-03-10', '2020-04-09'
'1234', '2020-04-10', '2020-05-10'
'1234', '2020-05-11', '2020-05-14'
'1234', '2020-05-15', '9999-12-31'
我曾尝试使用 LEAD 和 LAG function 但它们没有给我额外的记录集。任何指针都会有很大帮助。
您可以尝试使用具有默认值的LEAD
:
SELECT
Prod_Id,
Begin_Version_dt,
COALESCE(End_Version_dt,
LEAD(Begin_Version_dt, 1, date '9999-12-31')
OVER (PARTITION BY Prod_Id ORDER BY Begin_Version_dt)) AS End_Version_dt
FROM yourTable
ORDER BY
Prod_Id,
Begin_Version_dt;
这里的逻辑是我们 select,如果可用,任何非NULL
结束版本日期。 如果最终版本日期不可用,我们希望在序列中的下一个开始日期前领先。 如果这也不可用,那么我们默认报告9999-12-31
作为结束版本日期。
您需要使用两个查询。 首先用于插入记录,然后用于更新日期,如下所示:
创建示例数据
SQL> CREATE TABLE yourTable AS (
2 SELECT '1234' AS Prod_Id, date '2020-03-10' AS Begin_Version_dt, date '2020-04-09' AS End_version_dt FROM dual UNION ALL
3 SELECT '1234', date '2020-04-10', date '2020-05-10' FROM dual UNION ALL
4 SELECT '1234', date '2020-05-11', date '9999-12-31' FROM dual
5 );
Table created.
SQL>
SQL> CREATE TABLE prod_table as
2 (SELECT 1234 AS PROD_ID, DATE '2020-05-15' AS TRANS_DATE FROM DUAL);
Table created.
当前数据视图:
SQL> SELECT * FROM YOURTABLE ORDER BY BEGIN_VERSION_DT;
PROD BEGIN_VER END_VERSI
---- --------- ---------
1234 10-MAR-20 09-APR-20
1234 10-APR-20 10-MAY-20
1234 11-MAY-20 31-DEC-99
SQL> select * from prod_table;
PROD_ID TRANS_DAT
---------- ---------
1234 15-MAY-20
您正在寻找的查询
SQL> INSERT INTO yourTable Y
2 SELECT PROD_ID, TRANS_DATE, TRANS_DATE FROM PROD_TABLE;
1 row created.
SQL>
SQL>
SQL> UPDATE YOURTABLE YY
2 SET END_VERSION_DT = COALESCE(
3 (SELECT LD_BEGIN_DT
4 FROM (SELECT Y.BEGIN_VERSION_DT,
5 Y.PROD_ID,
6 LEAD(Y.BEGIN_VERSION_DT)
7 OVER (PARTITION BY Y.PROD_ID
8 ORDER BY Y.BEGIN_VERSION_DT) - 1 AS LD_BEGIN_DT
9 FROM YOURTABLE Y) Y
10 WHERE YY.PROD_ID = Y.PROD_ID
11 AND YY.BEGIN_VERSION_DT = Y.BEGIN_VERSION_DT),
12 DATE '9999-12-31');
4 rows updated.
更新数据:
SQL> SELECT * FROM YOURTABLE ORDER BY BEGIN_VERSION_DT;
PROD BEGIN_VER END_VERSI
---- --------- ---------
1234 10-MAR-20 09-APR-20
1234 10-APR-20 10-MAY-20
1234 11-MAY-20 14-MAY-20
1234 15-MAY-20 31-DEC-99
SQL>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.