对SQL有点陌生--数据库是Snowflake,我相信是ANSI标准的
主表如下所示。由于每当报告一个新的问题时,就会增加一条新的记录,因此可以将相同的IssueUPCWarehouseDate组合在一起。其他列存在,但不应该影响这个问题。
我想弄明白的是排除列--如果所需的IssueUPCWarehouse和Date组合在排除表中,它应该是'Y',如下图所示。
棘手的部分是LEVEL列,定义了UPCIssueWarehouse组合是否必须匹配,或者只是UPCIssue,或者只是UPC。另外,主表中的记录必须落在Date范围内才能排除。
从外观上看,预期的结果是这样的
这个方案只对一级(IssueUPCWarehouse)有效,但我想不出如何做另外两级而不重叠,不存在意外排除记录的可能。
update t
set exclude = 'Y'
where exists (select 1
from exclusions e
where e.issue_code = t.issue_code and
e.upc = t.upc and
e.warehouse = t.warehouse and
t.date between e.date_from and e.date_to);
大卫的回答 已经涵盖了采取的正确方法,用 CASE
条件表达式但要确保你的查询也将级别检查显式地包含在每个条件中。这里有一个啰嗦的例子,我没有听懂你的解决方案,但你可以用case语句处理列的多个不同情况输出。
update t
set exclude = case
when exists(
select 1
from exclusions e
where
e.warehouse = t.warehouse
and e.upc = t.upc
and e.issue_code = t.issue_code
and t.date between e.date_from and e.date_to
and e.level = 'UPC/ISSUE/WAREHOUSE'
) then 'Y'
when exists(
select 1
from exclusions e
where
e.issue_code = t.issue_code
and e.upc = t.upc
and t.date between e.date_from and e.date_to
and e.level = 'UPC/ISSUE'
) then 'Y'
when exists(
select 1
from exclusions e
where
e.upc = t.upc
and t.date between e.date_from and e.date_to
and e.level = 'UPC'
) then 'Y'
else ''
end;
我不明白你的解决方案有什么不足之处 但你可以用case语句来处理列的多个不同的情况输出 只有第一个匹配的才会应用,这样可以防止重叠。
就像这样。
update t
set exclude = CASE
WHEN EXISTS
(select 1
from exclusions e
where e.issue_code = t.issue_code and
e.upc = t.upc and
e.warehouse = t.warehouse and
t.date between e.date_from and e.date_to
) THEN 'Y'
WHEN --Other situation where it meets your criteria
THEN 'Y'
ELSE 'N'
END
;
你也可以用这个来反转你的逻辑,指定 "N "种情况,然后默认为 "Y",如果这样更合理的话。
如果我忽略了 level
列,那么我可以直接使用 null
看看是否有匹配的。 如果这就够了,那么。
update t
set exclude = 'Y'
where exists (select 1
from exclusions e
where (e.issue_code = t.issue_code or e.issue_code is null) and
(e.upc = t.upc or e.upc is null) and
(e.warehouse = t.warehouse or e.warehouse is null) and
t.date between e.date_from and e.date_to
);
你 可以 使用 level
也是一列(我认为上面的内容更清楚)。 类似这样。
update t
set exclude = 'Y'
where exists (select 1
from exclusions e
where (e.issue_code = t.issue_code or e.level not like '%ISSUE%') and
(e.upc = t.upc or e.level not like '%UPC%') and
(e.warehouse = t.warehouse or e.level like '%WAREHOUSE%') and
t.date between e.date_from and e.date_to
);
我同意David所说的,你需要的是一个带有case语句的更新。要小心使用case语句--只有满足第一个条件的才会被执行。所以先为最常见的情况编码,然后是下一个最常见的...最后是最不常见的条件。