我们有一个定期运行并验证货件数据的批处理,然后将与错误有关的行转储到名为AN_VALIDATION_ERRORS表的表中。
第一次运行时,我可以获得看起来像这样的数据(生病做一个每个级别都有错误的例子):
error_seq | asn | po | carton | upc | error_code | error_origin | error_level
--------------------------------------------------------------------
1 | 1 | null | null | null | SO | B | S -- shipment
2 | 1 | 90 | null | null | NF | B | O -- order
3 | 1 | 92 | 45 | null | SC | B | C -- carton
4 | 1 | 92 | 45 | 567 | ST | B | I -- item
重新验证数据后,批处理只会将更多行转储到此表中,但不会清理旧行。但是,有一点不同,随后的时间,它会转储有error_origin =' S'。数据现在看起来像这样:
error_seq | asn | po | carton | upc | error_code | error_origin | error_level
--------------------------------------------------------------------
1 | 1 | null | null | null | SO | B | S -- shipment
2 | 1 | 90 | null | null | NF | B | O -- order
3 | 1 | 92 | 45 | null | SC | B | C -- carton
4 | 1 | 92 | 45 | 567 | ST | B | I -- item
5 | 1 | 92 | 45 | null | SC | S | C -- new row
这意味着,所有未重新创建的行都被清除,并且持续存在的错误是错误原因为' S'。在我的示例中,error_seq 3和5是相同的错误,其余的被清除或修复。
我很容易通过选择error_origin =' S'来获取当前错误的列表。在一行有一个' S的情况下。但是,我还需要能够获得以前修复过的错误列表。在我的例子中,这将是error_seq {1,2,4}的行。
这是我试过的,这是错误的,但作为我尝试做什么的想法:
WITH B_LIST AS (
SELECT *
FROM ASN.AN_VALIDATION_ERRORS
WHERE ERROR_ORIGIN = 'B'
AND INTERNAL_ASN = 1
)
, S_LIST AS (
-- ALL OPEN ERRORS
SELECT *
FROM ASN.AN_VALIDATION_ERRORS
WHERE ERROR_ORIGIN = 'S'
AND INTERNAL_ASN = 1
)
, CLOSED_LIST AS (
-- TRY TO GET ALL ROWS WITH ERROR_ORIGIN = 'B' WHERE A CORRESPONDING ROW OF ERROR_ORIGIN = 'S' DOES NOT EXIST
SELECT *
FROM B_LIST BL
WHERE NOT EXISTS (
SELECT *
FROM S_LIST SL
WHERE SL.ORIG_PO_NO = BL.PO_NO
AND SL.CARTON_NO = BL.CARTON_NO
AND SL.UPC_NO = BL.UPC_NO
AND SL.ERROR_CODE = BL.ERROR_CODE
)
)
SELECT * FROM CLOSED_LIST;
此查询需要为我提供已修复的所有错误的列表,并以我的数据为例,结果必须是:
error_seq | asn | po | carton | upc | error_code | error_origin | error_level
--------------------------------------------------------------------
1 | 1 | null | null | null | SO | B | S -- shipment
2 | 1 | 90 | null | null | NF | B | O -- order
4 | 1 | 92 | 45 | 567 | ST | B | I -- item
答案 0 :(得分:2)
以前修复的错误是那些最近没有“S”的行。我对行之间的实际匹配条件有点不清楚,所以我猜它是asn
和error_code
。
您可以使用not exists
得到您想要的内容,如下所示:
select cl.*
from ASN.AN_VALIDATION_ERRORS ve
where error_origin = 'B' and
not exists (select 1
from ASN.AN_VALIDATION_ERRORS ve2
where ve2.asn = ve.asn and
ve2.error_code = ve.error_code and
ve2.id > ve.id and
ve2.error_origin = 'S'
);
编辑:
有关匹配列的完整列表(也可以是NULL
):
select cl.*
from ASN.AN_VALIDATION_ERRORS ve
where error_origin = 'B' and
not exists (select 1
from ASN.AN_VALIDATION_ERRORS ve2
where ve2.asn = ve.asn and
ve2.error_code = ve.error_code and
(ve2.po = ve.po or ve2.po is null and ve.po is null) and
(ve2.carton = ve.carton or ve2.carton is null and ve.carton is null) and
(ve2.upc = ve.upc or ve2.upc is null and ve.upc is null) and
ve2.id > ve.id and
ve2.error_origin = 'S'
);