SQL有点新-数据库是Snowflake,我相信它是ANSI
主表如下所示。相同发行/ UPC /仓库/日期的组合是可能的,因为每当报告新发行时都会添加新记录。存在其他列,但不应影响此问题
排除栏是我要弄清楚的-如果“排除”表中的Issue / UPC / Warehouse和Date所需的组合位于“ Y”,如下所示。
棘手的部分是LEVEL列,用于定义UPC /问题/仓库组合是否必须匹配,还是仅UPC /问题,还是UPC。另外,主表中的记录必须在“日期”范围内才能排除。
视觉上,预期的结果是这个
此解决方案仅适用于一个级别(问题/ UPC /仓库),但我无法弄清楚如何在不重叠的情况下执行另外两个级别,并且无法排除意外记录。
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);
答案 0 :(得分:2)
我没有关注您缺少的解决方案,但是您可以使用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”。
答案 1 :(得分:2)
David's answer已涵盖使用CASE
conditional expression的正确方法,但请确保您的查询还将级别检查显式纳入每个条件。这是一个详细的示例:
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;
答案 2 :(得分:1)
如果我忽略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
);
答案 3 :(得分:0)
我同意戴维所说的,您需要的是对案例陈述的更新。 请谨慎对待case语句-仅执行符合条件的第一个条件。 因此,首先针对最常见的情况编写代码,然后针对最不常见的条件编写下一个最常见的代码。