我想避免重复使用子查询。我的查询如下:
;WITH Temp(Ticker, FromDate, ToDate, BuyingQty, SellingQty, ABP, ASP)
AS
(
select
Ticker,
min(trxdate) as FromDate,
max(TrxDate) as ToDate,
case buysell when 'b' then SUM(Lot) end as BuyingQty,
case buysell when 's' then SUM(Lot) end as SellingQty,
case buysell when 'b' then CAST(SUM(Lot * price)/SUM(Lot) AS Decimal(10,2)) end as ABP,
case buysell when 's' then cast(SUM(Lot * price)/SUM(Lot) AS Decimal(10,2)) end as ASP
from transaksi where SettleDate is null
group by Ticker, buysell
)
select Ticker,
Min(FromDate) as FromDate,
Min(ToDate) as ToDate,
DATEDIFF(day, min(FromDate), max(ToDate)) as Days,
SUM(buyingQty) as BuyingQty,
SUM(sellingQty) as SellingQty,
case when(sum(sellingQty) is null) then SUM(BuyingQty) else SUM(buyingQty) - SUM(sellingQty) end as BalQty,
SUM(ABP) as ABP,
SUM(ASP) as ASP,
(SUM(ASP) - SUM(ABP)) * SUM(SellingQtY) AS Profit,
cast((SUM(ASP) - SUM(ABP)) / sum(ABP) * 100 as decimal(10,2)) AS [Profit%],
(select curprice from Stock where Temp.Ticker = Stock.Ticker) AS [Cur Price],
(select curprice from Stock where Temp.Ticker = Stock.Ticker) *
case when(sum(sellingQty) is null) then SUM(BuyingQty) else (SUM(buyingQty) - SUM(sellingQty)) end as [Cur. Value]
from Temp group by Ticker order by 1,2
请注意,我每次查询balQty
和CurPrice
两次。这会影响效率以及如何避免它?
balQty:
case when(sum(sellingQty) is null)
then SUM(BuyingQty)
else SUM(buyingQty) - SUM(sellingQty)
end
curprice:
select curprice
from Stock
where Temp.Ticker = Stock.Ticker
如何在CTE中使用变量?谢谢。
答案 0 :(得分:0)
您可以使用Cross Apply
来避免重复balQty
逻辑。您可以left join
与Stock
一起使用cur price
。
在CTE中使用Variable
与在常规查询中使用相同。添加了一个新变量@buysell
来演示。
Declare @buySell varchar(1)
SET @buySell = 'a'
;WITH Temp(Ticker, FromDate, ToDate, BuyingQty, SellingQty, ABP, ASP)
AS
(
select
Ticker,
min(trxdate) as FromDate,
max(TrxDate) as ToDate,
case buysell when 'b' then SUM(Lot) end as BuyingQty,
case buysell when 's' then SUM(Lot) end as SellingQty,
case buysell when 'b' then CAST(SUM(Lot * price)/SUM(Lot) AS Decimal(10,2)) end as ABP,
case buysell when 's' then cast(SUM(Lot * price)/SUM(Lot) AS Decimal(10,2)) end as ASP
from transaksi where SettleDate is null
and buysell = @buysell
group by Ticker, buysell
)
select T.Ticker,
Min(FromDate) as FromDate,
Min(ToDate) as ToDate,
DATEDIFF(day, min(FromDate), max(ToDate)) as Days,
SUM(buyingQty) as BuyingQty,
SUM(sellingQty) as SellingQty,
SUM(C1.BalQty) AS BalQty,
SUM(ABP) as ABP,
SUM(ASP) as ASP,
(SUM(ASP) - SUM(ABP)) * SUM(SellingQtY) AS Profit,
cast((SUM(ASP) - SUM(ABP)) / sum(ABP) * 100 as decimal(10,2)) AS [Profit%],
SUM(S.curprice) AS [Cur Price],
SUM(S.curprice * C1.BalQty) as [Cur. Value]
from Temp T
LEFT JOIN Stock S ON T.Ticker = S.Ticker
CROSS APPLY (
SELECT case when(T.sellingQty is null) then T.BuyingQty else T.buyingQty - T.sellingQty end AS BalQty
) C1
group by T.Ticker order by 1,2
方法2
;WITH Temp(Ticker, FromDate, ToDate, BuyingQty, SellingQty, ABP, ASP)
AS
(
select
Ticker,
min(trxdate) as FromDate,
max(TrxDate) as ToDate,
case buysell when 'b' then SUM(Lot) end as BuyingQty,
case buysell when 's' then SUM(Lot) end as SellingQty,
case buysell when 'b' then CAST(SUM(Lot * price)/SUM(Lot) AS Decimal(10,2)) end as ABP,
case buysell when 's' then cast(SUM(Lot * price)/SUM(Lot) AS Decimal(10,2)) end as ASP
from transaksi where SettleDate is null
group by Ticker, buysell
)
,CTE2 AS
(
select T.Ticker,
Min(FromDate) as FromDate,
Min(ToDate) as ToDate,
DATEDIFF(day, min(FromDate), max(ToDate)) as Days,
SUM(buyingQty) as BuyingQty,
SUM(sellingQty) as SellingQty,
SUM(ABP) as ABP,
SUM(ASP) as ASP,
(SUM(ASP) - SUM(ABP)) * SUM(SellingQtY) AS Profit,
cast((SUM(ASP) - SUM(ABP)) / sum(ABP) * 100 as decimal(10,2)) AS [Profit%],
S.curprice AS [Cur Price],
from Temp T
LEFT JOIN Stock S ON T.Ticker = S.Ticker
group by T.Ticker order by 1,2
)
SELECT
Ticker,
FromDate,
ToDate,
Days,
BuyingQty,
SellingQty,
C1.BalQty,
ABP,
ASP,
Profit,
[Profit%],
[Cur Price],
[Cur Price]*C1.BalQty AS [Cur Val]
FROM CTE2 T
CROSS APPLY (
SELECT case when(T.sellingQty is null) then T.BuyingQty else T.buyingQty - T.sellingQty end AS BalQty
) C1