显示每个销售的库存详情

时间:2016-06-06 14:33:45

标签: sql sql-server sql-server-2012

我试图通过将每个客户的销售分组来从ProdcutStock表中选择数据。

我的表格如下

SalesMaster

Id  CustId  TDate
1   2       2016-06-03
2   1       2016-06-03
3   2       2016-06-06
4   2       2016-06-06
5   1       2016-06-06
6   3       2016-06-06

SalesDetails

Id  SalesId ProductId   Qty
1   1       2       4.00
2   1       1       5.00
3   2       2       21.00
4   2       2       88.00
5   2       1       8.00
6   2       3       9.00
7   2       3       4.00
8   2       1       77.00
9   2       2       4.00
10  2       3       8.00
11  2       2       7.00
12  3       2       41.00
13  3       3       10.00
14  4       2       25.00
15  4       1       49.00
16  5       3       50.00
17  5       1       50.00
18  6       2       10.00
19  6       3       20.00

ProductStock

Id  Date    OpeningStock    TotalProduction TotalSales  ClosingStock
1   2016-06-05  100.00      0.00            0.00        100.00
2   2016-06-06  100.00      325.00          255.00      170.00
3   2016-06-07  200.00      0.00            0.00        200.00
5   2016-06-08  200.00      0.00            0.00        200.00
6   2016-06-09  200.00      0.00            0.00        200.00
7   2016-06-10  200.00      0.00            0.00        200.00

我想要实现的是下表

Date    OpeningStock    Production  Sales   Customer    ClosingStock
2016-06-05  100.00      0.00        0.00    NULL        100.00
2016-06-06  100.00      325.00      125.00  XYZ         300.00
2016-06-06  300.00      0.00        30.00   ABC         270.00
2016-06-06  270.00      0.00        100.00  PQR         170.00
2016-06-07  170.00      0.00        0.00    NULL        200.00

我使用以下代码获得的信息:(请参阅打开和关闭库存

Date    Opening Production  Sales   Name    Closing
2016-06-05  100.00  0.00    0.00    NULL    100.00
2016-06-06  100.00  325.00  125.00  XYZ     300.00
2016-06-06  100.00  325.00  30.00   ABC     395.00
2016-06-06  100.00  325.00  100.00  PQR     325.00
2016-06-07  200.00  0.00    0.00    NULL    200.00

我所做的如下:

SELECT PS.Date, PS.OpeningStock , PS.TotalProduction
, SUM(COALESCE(SD.Qty,0)) AS SALES, CM.Name
, (COALESCE(PS.OpeningStock,0)) + COALESCE(PS.TotalProduction,0) - SUM(COALESCE(SD.Qty,0)) AS ClosingStock
FROM ProductStock PS LEFT JOIN SalesMaster SM ON PS.Date = SM.Date
LEFT JOIN SalesDetails SD ON SM.Id = SD.SalesId
LEFT JOIN CustomersMaster CM ON SM.CustomerId = CM.Id
GROUP BY PS.Date, CM.Name, PS.OpeningStock, PS.TotalProduction
ORDER BY PS.Date

我还尝试使用LAG,因为我正在使用SQL Server 2012,但我没有得到如何申请。

2 个答案:

答案 0 :(得分:3)

这应该让你接近。您可以使用SUM()OVER()来获得SALES的运行总计,并使用它来计算数量。

;WITH ProductDetail AS (
    SELECT  ps.[Date],
            ps.OpeningStock,
            ps.TotalProduction,
            ps.ClosingStock,
            sm.CustId,
            COALESCE(SUM(Qty),0) Sales,
            ROW_NUMBER() OVER (PARTITION BY ps.[Date] ORDER BY CustID) Rn,
            SUM(SUM(Qty)) OVER (PARTITION BY ps.[Date] ORDER BY CustID) SalesRunningTotal
    FROM    ProductStock ps
            LEFT JOIN SalesMaster sm ON ps.[Date] = sm.[Date]
            LEFT JOIN SalesDetail sd ON sd.SalesID = sm.ID
    GROUP BY ps.[Date],
            ps.OpeningStock,
            ps.TotalProduction,
            ps.ClosingStock,
            sm.CustId
)
SELECT  [Date],
        CASE WHEN Rn = 1 THEN OpeningStock ELSE OpeningStock + (TotalProduction - SalesRunningTotal + Sales) END OpeningStock,
        CASE WHEN Rn = 1 THEN TotalProduction ELSE 0 END [Production],
        Sales,
        CustId,
        CASE WHEN Rn = 1 THEN OpeningStock + TotalProduction - Sales 
            ELSE OpeningStock + (TotalProduction - SalesRunningTotal) 
            END [ClosingStock]
FROM    ProductDetail

答案 1 :(得分:0)

我认为问题在于您没有直接引用 ProductStock 中的ID。您是否注意到错误的信息直接来自 ProductStock ?例如,对于重复三次的日期,2016-06-06,所有三个都是100,但在 ProductStock 上,只有第一个是100.再次 TotalProduction 。当只有第一个是325时,所有三个都是325.由于你只按日期而不是ID来引用它们,它们将提取不正确的信息(如果你不打算使用它,ID的重点是什么?吗)。

2016-06-06 a
2016-06-06 b
2016-06-06 c

从我刚刚创建的这个集合中看,我无法根据日期(这是您的查询尝试执行的操作)提取正确的字母。如果我想,在这个特定的情况下,我将不得不通过字母订购,然后根据其行号得到字母(行号将等于字母表中的序列)。

1 2016-06-06 a
2 2016-06-06 b
3 2016-06-06 c

现在我不必使用行号。我有一个ID,所以我可以简单地使用它来获取我想要的信息。您在ProductStock中缺少ID的使用。

(您的查询未触及)

FROM ProductStock PS LEFT JOIN SalesMaster SM ON PS.Date = SM.Date
LEFT JOIN SalesDetails SD ON SM.Id = SD.SalesId
LEFT JOIN CustomersMaster CM ON SM.CustomerId = CM.Id
GROUP BY PS.Date, CM.Name, PS.OpeningStock, PS.TotalProduction
ORDER BY PS.Date

您引用的唯一ID是 SalesMaster CustomersMaster 中的客户ID以及 SalesMaster SalesDetails 。在这种情况下,因为你已经拥有了所有你的加入,你可以简单地在最后添加一个 WHERE 子句......

WHERE PS.ID = SM.ID

我希望这会有所帮助:)