views:

117

answers:

2

I'm looking for a way to optimise the following:

SELECT 
    (SELECT SUM(amount) FROM Txn_Log WHERE gid=@gid AND txnType IN (3, 20)) AS pendingAmount,
    (SELECT COUNT(1) FROM Txn_Log WHERE gid = @gid AND txnType = 11) AS pendingReturn,
    (SELECT COUNT(1) FROM Txn_Log WHERE gid = @gid AND txnType = 5) AS pendingBlock

where @gid is a parameter and gid is an index field on this table. Problem: each sub-query reruns on the same set of entries - three reruns are two too many.

+4  A: 

You can do like this:

select
   sum(case when txnType in (3,20) then amount else 0 end) as pendingAmount,
   sum(case txnType when 11 then 1 else 0 end) as pendingReturn,
   sum(case txnType when 5 then 1 else 0 end) as pendingBlock
from
   Txn_Log
where
   gid = @gid
Guffa
Very good, you can also limit the initial select with the txnType IN (3, 20, 11, 5)
astander
Also, make use of indexes for both the [gid] and [txnType] fields, and maybe even [amount] to avoid the query ever even looking at the table itself. The most benefit coming from a covering index on [gid], [txnType], [amount]
Dems
+1  A: 

Can you not do something like this

SELECT sum(amount),count(1), txnType
FROM Txn_log
WHERE gid = @gid AND
    txnType in (3,5,11,20)
group by txnType

and then handle the rest of it programmatically?

Ron Tuffin