I am trying to compare two sets of transactions. One is from a store log and the other is from the accounting records. I have a with statement that creates a table comparing both transactions and includes any that do not match. This table is called 'compare'
Now I am trying to figure out why certain values may not be present in compare so I am adding a case when statement. Here is what I have so far
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
So when I only have the first case (Match), my query runs fast. When I add the second one it slows down. Essentially, what I am checking is if there is a store transaction that was rung up by the cashier and then canceled. If so, then the amount would be the same just the opposite ($5 versus -$5) and the store transaction id would be the same. I wouldn't expect a reversed transaction to be on the accounting record, since the item has not left the store. Any ideas on how to optimize the query run time? I have already added the additional case and moved from is not null to the when exists statement.
this isn't tested of course - let's say I'm taking a stab at it but you will have to let me know how it works.
main idea: get rid of the correlation subqueries and use sum/group by instead.
There should be 3 cases that may or may not cover all cases (I suppose they should but you can test out that theory by changing my inner join to a left join and see if there are null results on the left side).
Clearly, indexing may help a lot. Such as an index on store_trans_id (including accting_trans_id and store_amount)
I don't know what (if) there is a primary key in the table so in the queries where I have c.PK <> c2.PK
that means the primary key on the table - though in this case the criteria can probably can also be omitted as the sum would still come out to 0 or non-zero and that's all we care about.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.