SAP B1使用pivot进行年度比较查询

时间:2018-06-08 08:06:06

标签: sql-server sap sapb1

要求:我想比较去年(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 有关。 谢谢。

1 个答案:

答案 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秒。