优化查询-在Case When中使用SELECT语句

ngynwnxp  于 2022-10-03  发布在  其他
关注(0)|答案(1)|浏览(201)

我正在尝试比较两组交易。一份来自商店日志,另一份来自会计记录。我有一条With语句,它创建一个比较两个事务的表,并包括任何不匹配的事务。这张表格叫做‘比较’。

现在我试图弄清楚为什么某些值可能不会出现在比较中,所以我添加了一个Case When语句。这是我到目前为止所拥有的

select distinct *, 
case
   when (store_trans_id is not null and acctng_trans_id is not null) then 'Match'
   when (acctng_trans_id is null) then
      case 
        when exists (select 1 from compare cc where c.store_trans_id = cc.store_trans_id 
                                              and c.store_amount = cc.store_amount * -1) 
        then 'Store item transaction reversed'
      end
   else 'Research further'
end as 'Comparison'
from compare c

因此,当我只有第一个案例(匹配)时,我的查询运行得很快。当我添加第二个时,它变慢了。本质上,我检查的是是否有一笔商店交易被收银员打了电话,然后被取消了。如果是,则金额将正好相反($5与-$5),商店交易ID将相同。我不指望冲销的交易会出现在会计记录上,因为商品还没有离开商店。对如何优化查询运行时有什么想法吗?我已经添加了额外的CASE,并从is NOT NULL移到了WHEN EXISTS语句。

yfwxisqw

yfwxisqw1#

当然,这还没有经过测试--假设我正在尝试它,但您必须让我知道它是如何工作的。

要点:去掉相关子查询,改用SUM/GROUP BY。

应该有3种情况可能涵盖所有情况,也可能不涵盖所有情况(我认为它们应该涵盖所有情况,但您可以通过将我的内部联接更改为左联接来测试该理论,并查看左侧是否有空结果)。

显然,索引可能会有很大帮助。例如store_tras_id上索引(包括accting_trans_id和store_mount)

我不知道表中有什么(如果)主键,所以在我有c.PK <> c2.PK的查询中,这意味着表上的主键-尽管在这种情况下,条件可能也可以省略,因为总和仍然是0或非零,这是我们所关心的。

select c.*, c2.[Comparison]
from compare c
inner /* left */ join
(
    -- case 1: acctg_trans_id is not null
    select 
        store_trans_id,
        'Match' as [Comparison]
    from compare c
    where 
        store_trans_id is not null 
        and acctng_trans_id is not null
    union all
    -- case 2: acctg_trans_id is null and two store amounts sum to 0
    select 
        c.store_trans_id,
        'Store item transaction reversed' as [Comparison]
    from 
        compare c
        inner join compare c2
        on c.store_trans_id = c2.store_trans_id
        and c.PK <> c2.PK
    where 
        c.acctng_trans_id is null
        having sum(c.store_amount) = 0
    union all
    -- case 3: acctg_trans_id is null and two store amounts do not sum to 0
    select 
        c.store_trans_id,
        'Research further' as [Comparison]
    from 
        compare c
        inner join compare c2
        on c.store_trans_id = c2.store_trans_id
        and c.PK <> c2.PK
    where 
        c.acctng_trans_id is null
    having 
        sum(c.store_amount) <> 0
) c2
on c.store_trans_id = c2.store_trans_id

相关问题