sql:根据另一个表中的不同条件设置条件值

ukqbszuj  于 2021-07-26  发布在  Java
关注(0)|答案(4)|浏览(476)

sql有点新-db是snowflake,我相信这是ansi
主表如下所示。由于每次报告新问题时都会添加新记录,因此可以将相同的问题/upc/仓库/日期组合在一起。存在其他列,但不应影响此问题

exclude列就是我想弄清楚的—如果所需的issue/upc/warehouse和date的组合在exclude表中,它应该是y,如下所示。

棘手的部分是level列,它定义了upc/issue/warehouse组合是必须匹配,还是只匹配upc/issue,还是只匹配upc。此外,主表中的记录必须在要排除的日期范围内。
从视觉上看,预期结果如下

这个解决方案只适用于一个级别(issue/upc/warehouse),但我不知道如何在没有重叠和排除事故记录的可能性的情况下执行其他两个级别。

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);
fykwrbwg

fykwrbwg1#

如果我忽略了 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
                 );
fnatzsnv

fnatzsnv2#

我同意大卫所说的,你需要的是一个案件陈述的更新。对case语句要小心一点-只有满足的第一个条件才会被执行。所以先为最常见的情况编写代码,然后再为最常见的情况编写代码。。最后是最不常见的标准。

o2g1uqev

o2g1uqev3#

大卫的回答涵盖了正确的方法,使用 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;
sz81bmfz

sz81bmfz4#

我并没有关注您的解决方案缺少什么,但是您可以使用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”。

相关问题