Запрос SAP B1 с использованием сводной таблицы для годового сравнения - PullRequest
0 голосов
/ 08 июня 2018

Требование : Я хочу сравнить продажи за год (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 голосов
/ 26 июля 2018

Проблема с вашим представлением - это подзапросы.Если вы хотите повысить производительность вашего запроса, вам следует избегать использования этих подзапросов.

Например, вы можете создать представление 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 секунда.

...