【问题标题】:History handling scenario issue历史处理场景问题
【发布时间】:2017-11-30 08:56:36
【问题描述】:

我需要查询帮助以处理以下情况。

以下记录处于活动状态:

ID          start_dt        status  end_dt
-------------------------------------------------
18,593,122  1/15/07 14:38   A       12/11/07 8:45
18,593,122  12/11/07 8:45   C       12/11/07 8:45
18,593,122  12/11/07 8:45   A       11/13/11 0:00
18,593,122  11/13/11 0:00   C       12/26/11 10:36
18,593,122  12/26/11 10:36  A       ?

以下已关闭:

ID          start_dt        status  end_dt
-------------------------------------------------
18,593,122  1/15/07 14:38   A       12/11/07 8:45
18,593,122  12/11/07 8:45   C       ?

我必须在记录未正确结束的表中插入记录。 例如,有如下记录:

ID          start_dt        status  end_dt
-------------------------------------------------
18,593,122  1/15/07 14:38   A       12/11/07 8:45

在上面的记录中缺少 Closed 记录。

我必须识别这些记录并插入到表中。

以下示例受到影响。

10,866  7/29/96 0:01    A       12/27/03 14:16
10,866  7/25/00 0:01    A       8/20/00 23:59
10,866  8/20/00 23:59   C       10/2/02 13:00
10,866  10/2/02 13:00   A       7/25/04 14:11
10,866  12/27/03 14:16  C       7/25/04 14:11
10,866  7/25/04 14:11   C       7/25/04 14:11
10,866  7/25/04 14:11   A       ?
10,866  5/28/11 16:24   T       5/28/11 16:24

以下场景无法处理: accs_meth_status_type_cd='A' 且结束日期不为空的记录(在下方突出显示)。 预期:应插入 accs_meth_status_type_cd='C' 的记录 实际:没有插入 accs_meth_status_type_cd='C' 的记录

10,866  7/29/96 0:01    A       12/27/03 14:16
10,866  7/25/00 0:01    A       8/20/00 23:59
10,866  8/20/00 23:59   C       10/2/02 13:00
10,866  10/2/02 13:00   A       7/25/04 14:11
10,866  12/15/04 14:16  A       ?

【问题讨论】:

  • 已关闭和已打开的记录似乎相同。有什么区别吗?两者都有end_dt = NULL 的最新记录?
  • 活动记录的结束日期为空,将没有状态为 c 的记录,关闭的记录有一个结束日期不为空的记录加上另一条状态为 c 和结束日期为空的记录

标签: teradata


【解决方案1】:

据我了解,正确关闭的记录(即 ID)包括:

  • 第 1 行:状态 “C”和 End_Dt 不为空
  • 第 2 行:状态 = 'C' 并且 End_Dt 为 NULL
  • 第 1 行的 End_Dt = 第 2 行的 Start_Dt

假设这是正确的,您可以执行以下操作来查找应该关闭的记录(即有第 1 行,但缺少第 2 行):

INSERT INTO mytbl (ID, Start_Dt, Status, End_Dt)
SELECT 
    a.ID, 
    a.End_Dt, -- Use the unclosed row's End_Dt as the Start_Dt for the new "to-be-inserted" row
    'C', 
    NULL
FROM mytbl a
WHERE a.status <> 'C' 
AND a.End_Dt IS NOT NULL -- Get rows that should be considered closed
AND (a.ID, a.End_Dt) NOT IN (
    -- Check for corresponding records that do not also have a 'C' row
    -- You can also do this as a LEFT JOIN above
    SELECT ID, Start_Dt 
    FROM mytbl 
    WHERE Status = 'C' -- Check for presence of 'C' rows
    AND End_Dt IS NULL -- Check
)
QUALIFY ROW_NUMBER() OVER(PARTITION BY a.ID ORDER BY End_Dt DESC) = 1 -- Only return one row per "unclosed" record
;

这不会处理所有的边缘情况,但它应该让你开始。让我知道这是否是您正在寻找的。​​p>

更新
我针对您提供的 5 个新行运行了上面的查询,这是我得到的结果:

    id      start_dt                    status  end_dt
1   10,866  7/25/2000 00:01:00.000000   A       8/20/2000 23:59:00.000000
2   10,866  8/20/2000 23:59:00.000000   C       10/2/2002 13:00:00.000000
3   10,866  7/29/1996 00:01:00.000000   A       12/27/2003 14:16:00.000000
4   10,866  10/2/2002 13:00:00.000000   A       7/25/2004 14:11:00.000000
5   10,866  12/27/2003 14:16:00.000000  A       ?
6   10,866  7/25/2004 14:11:00.000000   C       ?

第 1-5 行是原始行。第 6 行是新插入的“C”行,对应于第 4 行,旧的不正确关闭的“A”行。这是你所期待的吗?

【讨论】:

  • 谢谢馄饨..会回复你的。 :)
  • 亲爱的@Ravioli,使用当前代码,临时终止的记录也将关闭,另一条记录将插入 C 。附上上述代码中的示例。请指教。
  • 如果您只想关闭缺少相应 'C' 行的 'A' 行,则将 WHERE 子句更改为:WHERE a.status = 'A' 查询期望 'C' 行具有Start_Dt 值 = 到“A”行的 End_Dt 值。如果“_Dt”值不匹配,则将其视为未关闭并插入新的“C”行。此外,此查询不会处理给定记录具有多个未闭合“A”行的情况。它只会查看最近的一个。在行序列中间正确插入“C”行需要更多逻辑。
  • 您能否修改您在上面发布的最新示例结果以显示“之前”行集和“之后”行集。这将有助于查看原始状态是什么以及添加了哪些行。
  • 感谢馄饨花时间。是的,我想关闭缺少相应“C”行的“A”行。我在哪里可以在非部分中添加该条件?此外,添加了无法处理的场景。我想我必须为它写另一个补丁。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 1970-01-01
  • 2015-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多