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
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