You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化SQL查询:统计发票头字段不一致的发票数量

需求说明

我们有一张表source_table1,其中invnum(发票号)、invamount(发票总金额)、descr(发票描述)属于发票头字段,这些字段在同一张发票的所有行中应保持一致,但目前存在每行重复存储的情况。需要统计存在头字段不一致的发票数量(比如示例数据中invnum=446的发票,其descr字段在某行出现了不一致的值)。

表创建语句

create table source_table1 (invnum, invamount,descr,linetype, amount, linenumber) as
  select 123,120,'desc1', 'ITEM', 100, 1 from dual union all
  select 123,120,'desc1', 'TAX' ,  20, 2 from dual union all
  select 446,220,'desc2', 'ITEM', 100, 1 from dual union all
  select 446,220,'desc2', 'ITEM', 100, 2 from dual union all
  select 446, 220,'desc22','TAX' ,  20, 3 from dual  union all
  select 500, 220,'desc3','ITEM' ,  220, 1 from dual

现有查询语句

select count(1) 
from (
    select count(invnum)
    from (
        select invnum,count(*) 
        from source_table1 
        group by invnum, invamount,descr
    ) 
    group by invnum
    having count(invnum) > 1
)

优化后的查询方案

以下几种方案逻辑更简洁,执行效率也更高:

方案一:窗口函数快速检测

仅扫描一次原表,通过窗口函数计算每个发票号下invamount和descr的唯一值数量,直接筛选出存在不一致的发票:

select count(distinct invnum)
from (
    select invnum,
           count(distinct invamount) over (partition by invnum) as amt_distinct_cnt,
           count(distinct descr) over (partition by invnum) as desc_distinct_cnt
    from source_table1
)
where amt_distinct_cnt > 1 or desc_distinct_cnt > 1

方案二:简化分组逻辑

利用Oracle支持多字段组合distinct的特性,直接统计每个发票下唯一的头字段组合数,超过1则说明存在不一致:

select count(*)
from (
    select invnum
    from source_table1
    group by invnum
    having count(distinct (invamount, descr)) > 1
)

方案三:关联查询定位(大数据量场景)

如果表数据量极大,且invnum字段有索引,可通过关联查询快速定位存在不一致的发票,减少后续计算量:

select count(distinct s1.invnum)
from source_table1 s1
where exists (
    select 1
    from source_table1 s2
    where s2.invnum = s1.invnum
      and (s2.invamount != s1.invamount or s2.descr != s1.descr)
)

内容的提问来源于stack exchange,提问作者Confused

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:43:12