【问题标题】:Auto incremental date field and version oracle sql for a table表的自动增量日期字段和版本 oracle sql
【发布时间】:2020-05-03 16:52:32
【问题描述】:

我有一个表,在这个表中我有数据没有正确加载数据完整性问题,因为这是一个维度表,我们需要正确维护有效_dt_from和有效_dt_to和版本,下面是表格和示例数据

create table TEST
(
LOC_SID NUMBER(38,0),
CITY VARCHAR2(180 BYTE),
POSTAL_CD VARCHAR2(15 BYTE),
EFFECTIVE_DT_FROM DATE,
EFFECTIVE_DT_TO DATE,
VERSION NUMBER(38,0)
);


Insert into TEST values (81910,'chicago',null,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('31.12.99 23:59:59','DD.MM.YY HH24:MI:SS'),1);
Insert into TEST values (81911,'chicago',null,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('31.12.99 23:59:59','DD.MM.YY HH24:MI:SS'),1);
Insert into TEST values (81912,'chicago',null,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('31.12.99 23:59:59','DD.MM.YY HH24:MI:SS'),1);
Insert into TEST values (81913,'chicago',null,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('31.12.99 23:59:59','DD.MM.YY HH24:MI:SS'),1);
Insert into TEST values (81914,'chicago',null,to_date('01.01.00 00:00:00','DD.MM.YY HH24:MI:SS'),to_date('31.12.99 23:59:59','DD.MM.YY HH24:MI:SS'),1);

数据完整性检查查询

SELECT count(*) AS RowAffected
FROM
  (SELECT LOC_SID,
          VERSION,
          EFFECTIVE_DT_FROM,
          EFFECTIVE_DT_TO,
          CITY,
          POSTAL_CD
   FROM
     (SELECT t.*,
             LEAD(EFFECTIVE_DT_FROM, 1) OVER(PARTITION BY CITY, POSTAL_CD
                                             ORDER BY EFFECTIVE_DT_FROM) AS next_date,
             LEAD(VERSION, 1) OVER(PARTITION BY CTY, POSTAL_CD
                                   ORDER BY EFFECTIVE_DT_FROM) AS next_version
      FROM TEST t)
   WHERE valid_to != next_date
     OR VERSION = next_version)

结果

CITY       POSTAL_CD   COUNT(*)

chicago    N/A         150

N/A        N/A          400

现有数据集

LOC_SID CITY    POSTAL_CD   EFFECTIVE_DT_FROM   EFFECTIVE_DT_TO   VERSION
81910   CHICAGO    N/A        01.01.1900          31.12.2199    1
81911   CHICAGO    N/A        01.01.1900          31.12.2199    1
81912   CHICAGO    N/A        01.01.1900          31.12.2199    1
81913   CHICAGO    N/A        01.01.1900          31.12.2199    1
81914   CHICAGO    N/A        01.01.1900          31.12.2199    1

预期数据集

LOC_SID CITY    POSTAL_CD   EFFECTIVE_DT_FROM   EFFECTIVE_DT_TO   VERSION
81910   CHICAGO    N/A        01.01.1900          01.01.2017       1
81911   CHICAGO    N/A        01.01.2017          02.01.2017       2
81912   CHICAGO    N/A        02.01.2017          03.01.2017       3
81913   CHICAGO    N/A        03.01.1900          04.01.2017       4
81914   CHICAGO    N/A        04.01.2017          31.12.2199       5

修复后运行 数据完整性检查查询我应该得到 0 行

如果我需要手动调整和更新的记录很少,我如何使 EFFECTIVE_DT_FROMEFFECTIVE_DT_TOVERSION 递增,但是我有很多行,如何解决这个问题?

我尝试了下面的查询,但这只会更新唯一的版本,但不能解决问题

merge into TEST a
using
(
select LOC_SID,CITY,POSTAL_CD,EFFECTIVE_DT_FROM,EFFECTIVE_DT_TO,VERSION
,rank() over(partition by CITY,POSTAL_CD order by LOC_SID ) rnk
from TEST
where CITY='CHICAGO'
)b
on (a.LOC_SID = b.LOC_SID)
when matched then update set 
a.VERSION=b.rnk;

我注意到我有一个场景

LOC_SID CITY    POSTAL_CD   EFFECTIVE_DT_FROM   EFFECTIVE_DT_TO  VERSION
25101   ASSAM   1153            01.01.1900          31.12.2199     1
25102   ASSAM   1153            01.01.1900          31.12.2199     1
25103   ASSAM   1290            01.01.1900          31.12.2199     1
25104   ASSAM   1290            01.01.1900          31.12.2199     1
25105   ASSAM   1310            01.01.1900          31.12.2199     1
25106   ASSAM   1310            01.01.1900          31.12.2199     1
25107   ASSAM   1781            01.01.1900          31.12.2199     1
25108   ASSAM   1781            01.01.1900          31.12.2199     1
25109   ASSAM   1982            01.01.1900          31.12.2199     1
25110   ASSAM   1982            01.01.1900          31.12.2199     1

我有 31 个这样的案例,当我尝试您的合并查询时它不起作用,我有以下结果集

LOC_SID  CITY    POSTAL_CD       EFFECTIVE_DT_FROM   EFFECTIVE_DT_TO  VERSION
    25101   ASSAM   1153            01.01.1900          01.01.2017          1
    25102   ASSAM   1153            01.01.1900          31.12.2199          1
    25103   ASSAM   1290            01.01.1900          01.01.2017          1
    25104   ASSAM   1290            01.01.1900          31.12.2199          1
    25105   ASSAM   1310            01.01.1900          01.01.2017          1
    25106   ASSAM   1310            01.01.1900          31.12.2199          1
    25107   ASSAM   1781            01.01.1900          01.01.2017          1
    25108   ASSAM   1781            01.01.1900          31.12.2199          1
    25109   ASSAM   1982            01.01.1900          01.01.2017          1
    25110   ASSAM   1982            01.01.1900          31.12.2199          1

【问题讨论】:

    标签: sql oracle date sql-update oracle-sqldeveloper


    【解决方案1】:

    我认为您使用mergerow_number() 的逻辑是正确的(尽管可能不需要partition by 子句,因为您已经在城市上进行过滤)。我用额外的逻辑扩展了它来处理日期:

    • 最初的effective_dt_from 和最后的effective_dt_to 应该保持不变

    • 在这两者之间,您希望从 '2017-01-01' 开始逐日递增日期。

    查询:

    merge into test t
    using (
        select
            t.*,
            row_number() over(order by loc_sid asc) rn,
            count(*) over() cnt
        from test t
        where city = 'Chicago'
    ) t1
    on (t1.loc_sid = t.loc_id)
    when matched the update set
        t.version = t1.rn,
        t.effective_dt_from = 
            case 
                when rn = 1 then t.effective_dt_from
                else date '2017-01-01' + rn - 2
            end,
        t.effective_dt_to = 
            case 
                when rn = cnt then t.effective_dt_to
                else date '2017-01-01' + rn - 1
            end
    

    【讨论】:

    • 嗨@GMB 感谢您调整我已经测试过它的查询,但我有一个新场景,上面的查询不起作用,有什么建议吗?
    • @rakesh:您应该为此提出一个新问题,提供示例数据和预期结果。
    猜你喜欢
    • 2011-11-09
    • 2015-11-03
    • 2015-12-30
    • 2016-01-18
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多