【问题标题】:SQL | Update query with left join and case conditionSQL |使用左连接和案例条件更新查询
【发布时间】:2020-08-17 23:35:37
【问题描述】:
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% 且之前没有条目时,Calc =2

当 per 从最后一个条目增加时,Calc =3

计算 = 4 当 per 比上一个条目减少时

【问题讨论】:

  • 您在标题中说“左连接”,但在您的问题正文中没有提及它,并且您只显示一张表格。我停止阅读,因为整件事已经没有意义了。请澄清您的问题 - 如果它与“加入”无关,请编辑您的标题以正确反映您的问题。
  • 另外:我看到四月的缩写在某些行中写为 Apr,在其他行中写为 apr(未大写),并且 ape 在最后一行。如果很难保持直截了当,那么编写正确的 SQL 肯定会更加困难,尤其是对于不平凡的问题。

标签: sql oracle merge oracle11g sql-update


【解决方案1】:

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

在下面的示例中,我假设 ID 和 DATE 列是演示表上的主键。 您应该检查 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

【讨论】:

  • 如果同一个 ID 有超过 2 条记录怎么办。然后我们需要将当前记录与最大日期的记录进行比较。
猜你喜欢
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 2016-02-17
  • 2023-01-18
  • 1970-01-01
  • 2021-12-25
  • 2019-06-17
  • 2016-05-02
相关资源
最近更新 更多