高级SQL:日期范围之间的销售总额

时间:2019-02-23 09:27:32

标签: sql sql-server tsql stored-procedures

我正在尝试获取某个日期范围内特定产品的销售总额。不幸的是,两个日期的结果所得的销售总额是相同的。正确地说,2019/01/01的总销售额是5000,第二天2019/01/02的总销售额是3000。结果显示两天的总销售额是8000。哪有错任何专家都可以帮助改进此查询吗?

Declare @BusinessDate datetime ='2019-01-01'
Declare @end datetime ='2019-01-02'
DECLARE @StoreId int = 100
SELECT  [Terminals].[Id] AS [TerminalId],
        [Terminals].[StoreId],
        [EOD].[Id] AS [EODId],
        SUM([Sales].[SalesAmount]) AS [SalesAmount],
        [EOD].BusinessDate
FROM    [CEPP]..[Stores] WITH (NOLOCK)
        INNER JOIN [CEPP]..[Terminals] WITH (NOLOCK)
 ON     [Stores].[Id] = [Terminals].[StoreId]
        AND [Terminals].[MWorkFlowStatusId] = 2
        AND ([Terminals].[MStatusId] = 1
        OR ([Terminals].[MStatusId] = 0
        AND [Terminals].[SuspendedDate] > @BusinessDate ))
        LEFT JOIN [EndOfDays] AS [EOD] WITH (NOLOCK)
 ON     [Terminals].[Id] = [EOD].[TerminalId]
        AND [EOD].[BusinessDate] >= @BusinessDate and [EOD].[BusinessDate]<=@end
        CROSS APPLY (
            SELECT SUM([Products].[Deno]) AS [SalesAmount]
            FROM [SalesOrders] AS [SO] WITH (NOLOCK)
                INNER JOIN [SalesTransactions] AS [ST] WITH (NOLOCK)
            ON  [SO].[Id] = [ST].[SalesOrderId]
                LEFT JOIN [VoidOrders] AS [VO] WITH (NOLOCK)
                INNER JOIN [VoidTransactions] AS [VT] WITH (NOLOCK)
            ON  [VO].[Id] = [VT].[VoidOrderId]
            ON  [SO].[DealerId] = [VO].[DealerId]
                AND [SO].[StoreId] = [VO].[StoreId]
                AND [SO].[TerminalId] = [VO].[TerminalId]
                AND [ST].[ProductId] = [VT].[ProductId]
                AND [ST].[SerialNo] = [VT].[SerialNo]
                AND [ST].[BusinessDate] = [VT].[BusinessDate]
                AND [VT].[MVoidTypeId] = 1
                INNER JOIN [CEPP].[dbo].[Products] WITH (NOLOCK)
            ON  [ST].[ProductId] = [Products].[Id]
            WHERE [EOD].[Id] IS NOT NULL
                AND [VT].[SerialNo] IS NULL
                AND [SO].[TerminalId] = [Terminals].[Id]
                AND [ST].[BusinessDate] >= @BusinessDate and [ST].[BusinessDate] <= @end
        ) AS [Sales]
WHERE  [Stores].[DealerId] = 1 AND (@StoreId IS NULL OR [Terminals].[StoreId] = @StoreId)
GROUP BY [Terminals].[Id], [Terminals].[StoreId], [EOD].[Id], [Stores].[Code], [Terminals].[Code],[EOD].BusinessDate
ORDER BY ISNULL([EOD].[Id], 0), [Stores].[Code], [Terminals].[Code]

我得到的意外结果是:

TerminalId  StoreId   EODId   SalesAmount   BusinessDate
  21598      100     5427531    8000.00    2019-01-01 00:00:00.000
  21598      100     5427532    8000.00    2019-01-02 00:00:00.000

结果应如下所示:

TerminalId  StoreId   EODId   SalesAmount   BusinessDate
  21598      100     5427531    5000.00    2019-01-01 00:00:00.000
  21598      100     5427532    3000.00    2019-01-02 00:00:00.000

2 个答案:

答案 0 :(得分:0)

我一眼便看到,没有测试数据,这是在CROSS APPLY中执行SUM([Products]。[Deno]),而与外部查询中的GROUP BY无关。因此,为什么要让每个输出行的SUM([Sales]。[SalesAmount])等于8000。

重构CROSS APPLY子查询以针对GROUP BY聚合SUM([Products]。[Deno]),然后使用GROUP BY谓词将外部表联接回主表。

答案 1 :(得分:0)

AND [EOD]。[BusinessDate]> = @BusinessDate和[EOD]。[BusinessDate] <= @ end

这部分对我来说非常可疑。我认为应该是

[EOD]。[BusinessDate] = [Sales]。[Date]

如果那不能解决您的问题,请向我们提供用于创建表和测试数据的脚本。这样,调查查询就容易得多。