SQL |使用左连接和案例条件更新查询

SQL | Update query with left join and case condition

TABLE A


ID , PER , DATE , CALC
1 , 11 , 1-Apr , 1
1 ,6, 2-Apr , 4
2 ,7 , 1-apr ,2
2 , 12 , 2-apr , 3
3 , 13 , 2-apr , 1
4 , 8 , 2-ape , 2

需要根据以下条件编写更新查询

计算列的条件是 Calc = 1 当 per 大于 10% 并且之前没有输入

当 per 大于 5% 且小于 10% 且之前没有输入时计算 =2

当 per 从最后一个条目增加时计算 =3

当 per 比上次输入减少时,Calc = 4

您可以使用 Oracle 的 LAG 函数访问上一行 (link)。剩下的是处理不同状态的大 CASE 语句。

在下面的示例中,我假设 ID 和 DATE 列是演示 table 中的主键。 您应该检查 NULL 用于 CALC 的部分(用 2 个问号标记)。这些是您的描述中未定义的状态。

BEGIN
    EXECUTE IMMEDIATE 'drop table table_a';
EXCEPTION
    WHEN OTHERS THEN NULL;
END;
/
create table table_a (
    "ID" number,
    "PER" number,
    "DATE" date,
    "CALC" number
);
/
insert into table_a 
select 1 "ID", 11 "PER", trunc(sysdate)-1 "DATE", null "CALC" from dual
union all
select 1 "ID", 6 "PER", trunc(sysdate) "DATE", null "CALC" from dual
union all
select 2 "ID", 7 "PER", trunc(sysdate)-1 "DATE", null "CALC" from dual
union all
select 2 "ID", 12 "PER", trunc(sysdate) "DATE", null "CALC" from dual
union all
select 3 "ID", 13 "PER", trunc(sysdate) "DATE", null "CALC" from dual
union all
select 4 "ID", 8 "PER", trunc(sysdate) "DATE", null "CALC" from dual
/

update table_a
set ("CALC") = (
    with tmp_prev as (
    select 
        "ID",
        "PER",
        "DATE",
        LAG("PER") OVER (PARTITION BY "ID" ORDER BY "ID","DATE") "PREV_PER"
    from table_a
    )
    select 
        case when "PREV_PER" is null 
            then
                case when "PER" > 10 then 1 
                else
                    case when "PER" > 5 and "PER" < 10 
                        then 2
                        else null -- ?? =10 or <=5
                    end
                end
            else
                case when "PER" > "PREV_PER" 
                    then 3
                    else 
                        case when "PER" < "PREV_PER"
                            then 4
                            else null -- ?? equal
                        end
                end
            end calc_new
    from tmp_prev
    where table_a."ID"=tmp_prev."ID" and table_a."DATE"=tmp_prev."DATE"
);
/

select * from table_a;
/

结果:

        ID        PER DATE           CALC
---------- ---------- -------- ----------
         1         11 02.05.20          1
         1          6 03.05.20          4
         2          7 02.05.20          2
         2         12 03.05.20          3
         3         13 03.05.20          1
         4          8 03.05.20          2