要求:我想比较去年(2018年)的销售额和毛利润(2017年)。 解决方案:我已尝试使用下面的查询,但我得到了预期的结果。
Month | prevSales | prevGP | currentSales | currGP
Jan | 1234567.00| 1234567.00| 1234567.00 | 1234567.00
Feb | 1234567.00| 1234567.00| 1234567.00 | 1234567.00
问题:查询花了很长时间才能生成结果,显示结果差不多一分钟。
SELECT P.[monName],
ISNULL([2017],0) as [prev],
ISNULL(P.[prevGP],0) [prevGP],
ISNULL([2018],0) as [curr],
ISNULL(P.[currGP],0) [currGP]
FROM (
SELECT LEFT(DATENAME(MONTH,T1.DocDate),3) [monName],
MONTH(T1.DocDate) [monNum],
ROUND((T1.Doctotal-T1.VatSum-T1.TotalExpns),0) AS [BAL],
(SELECT Sum(A.GrosProfit)
FROM OINV A
WHERE A.CANCELED='N' AND A.DocStatus='C' AND RIGHT(A.NumAtCard,9)<>'CANCELLED'
AND YEAR(A.DocDate)=YEAR(GETDATE())-1 AND MONTH(A.DocDate)=MONTH(T1.DocDate) ) [prevGP],
(SELECT SUM(B.GrosProfit)
FROM OINV B
WHERE B.CANCELED='N' AND B.DocStatus='C' AND RIGHT(B.NumAtCard,9)<>'CANCELLED'
AND YEAR(B.DocDate)=YEAR(GETDATE()) AND MONTH(B.DocDate)=MONTH(T1.DocDate) ) [currGP],
year(T1.Docdate) as [year]
FROM dbo.OCRD T0
LEFT JOIN dbo.OINV T1 ON T1.CardCode = T0.CardCode
Where RIGHT(T1.Numatcard,9)<>'CANCELLED' AND T1.CANCELED='N'
AND T0.[CardType] ='C' AND T1.DocStatus='C'
) S
PIVOT ( SUM(S.[BAL]) FOR [year] IN ([2017],[2018])) P
我可以做些什么来使 查询有效 。我认为与 pivot 有关。 谢谢。
答案 0 :(得分:0)
您的视图问题是子查询。如果要提高查询的性能,则需要避免使用这些子查询。
例如,您可以创建一个返回所需信息的sql视图。然后,将您当前的查询与该视图合并,然后删除子查询。
您可以这样做。
create view InvoiceInfoByMonth
as
select sum(GrosProfit) as GrosProfit, year(docdate) as DocYear, month(docdate) as DocMonth
from OINV
WHERE CANCELED='N' AND DocStatus='C' AND RIGHT(NumAtCard,9)<>'CANCELLED'
group by year(DocDate), month(DocDate)
GO
SELECT P.[monName],
ISNULL([2017],0) as [prev],
ISNULL(P.[prevGP],0) [prevGP],
ISNULL([2018],0) as [curr],
ISNULL(P.[currGP],0) [currGP]
FROM (
SELECT LEFT(DATENAME(MONTH,T1.DocDate),3) [monName],
MONTH(T1.DocDate) [monNum],
ROUND((T1.Doctotal-T1.VatSum-T1.TotalExpns),0) AS [BAL],
T2.GrosProfit as prevGP, T3.GrosProfit as currGP,
year(T1.Docdate) as [year]
FROM dbo.OCRD T0
LEFT JOIN dbo.OINV T1 ON T1.CardCode = T0.CardCode
left join InvoiceInfoByMonth T2 ON T2.DocYear = year(getdate())-1 and month(T1.DocDate) = T2.DocMonth
left join InvoiceInfoByMonth T3 ON T3.DocYear = year(getdate()) and month(T1.DocDate) = T3.DocMonth
Where RIGHT(T1.Numatcard,9)<>'CANCELLED' AND T1.CANCELED='N'
AND T0.[CardType] ='C' AND T1.DocStatus='C'
) S
PIVOT ( SUM(S.[BAL]) FOR [year] IN ([2017],[2018])) P
在我的系统中,查询执行时间从1分钟缩短到1秒。