改进包含多个子查询的SQL查询

时间:2018-05-29 07:58:43

标签: sql

我有一个SQL查询场景我已经遇到过几次,输出是正确的但我想知道是否有更好的方法来做它因为我觉得我重复相同的公式很多次并且运行太多子查询

 select s.StockId,

-- THESE ARE ALL REPEATED - CAN I GET ALL VALUES IN 1 QUERY?
isnull((select top 1 Cost from StockCosts sc where sc.Disabled = 0 and sc.StockId = s.StockId and ChargeType = 1),0) as VendorRecovery,
isnull((select top 1 Cost from StockCosts sc where sc.Disabled = 0 and sc.StockId = s.StockId and ChargeType = 2),0) as VendorCommission,

--THESE BOTTOM 3 ARE TO GET THE TOTALS, AGAIN REPEATED STATEMENTS?
(select SUM(Cost) from StockCosts sc where sc.Disabled = 0 and sc.StockId = s.StockId ) as VendorChargesNet,
(select (SUM(Cost) / 100) * st.VATRate from StockCosts sc where sc.Disabled = 0 and sc.StockId = s.StockId ) as VendorChargesVAT,
(select SUM(Cost) + (SUM(Cost) / 100) * st.VATRate from StockCosts sc where sc.Disabled = 0 and sc.StockId = s.StockId ) as VendorChargesTotal

from SaleTrans st 
inner join Stock s on st.StockId = s.StockId 

2 个答案:

答案 0 :(得分:1)

相关标量子查询通常可以重写为外部联接。

当您使用相同的条件多次访问同一个表时,您可以将它们组合成一个派生表(或公用表表达式)。

这可能会返回相同的结果:

select sc.*
from SaleTrans st 
inner join Stock s
left join 
 ( select
      min(case when ChargeType = 1 then cost end) as VendorRecovery -- or MAX?
     ,min(case when ChargeType = 2 then cost end) as VendorCommission
     ,SUM(Cost) as VendorChargesNet
     ,(SUM(Cost) / 100) * st.VATRate as VendorChargesVAT
     ,SUM(Cost) + (SUM(Cost) / 100) * st.VATRate as VendorChargesTotal
   from StockCosts sc 
   where sc.Disabled = 0
   group by sc.StockId
 ) as sc
on sc.StockId = s.StockId

答案 1 :(得分:0)

我只会使用条件聚合:

select s.StockId,
       max(case when sc.ChargeType = 1 then sc.Cost else 0 end) as VendorRecovery,
       max(case when sc.ChargeType = 2 then sc.Cost else 0 end) as VendorCommission,
       sum(case when sc.Disabled = 0 then sc.Cost end) as VendorChargesNet,
       sum(case when sc.Disabled = 0 then sc.Cost / 100 end) * st.VATRate as VendorChargesVAT,
       sum(case when sc.Disabled = 0 then sc.Cost + (sc.Cost / 100) * st.VATRate end) as VendorChargesTotal
from Stock s join
     SaleTrans st 
     on st.StockId = s.StockId left join
     StockCosts sc
     on sc.StockId = s.StockId 
group by s.StockId, st.VATRate