Sql server 如何在SQL Server 2008查询中显示订单履行情况

Sql server 如何在SQL Server 2008查询中显示订单履行情况,sql-server,sql-server-2008,tsql,cumulative-sum,fulfillment,Sql Server,Sql Server 2008,Tsql,Cumulative Sum,Fulfillment,我正试图在SQL Server 2008数据库中想出一种方法,通过销售订单表获取零件的未结需求,按到期日订购,然后查看采购订单表,按采购订单完成销售订单,并按到期日订购采购订单供应。同时,我需要显示哪些采购订单正在履行销售订单 例如: SO表格 SO# DueDate Part Number Required QTY --------------------------------------------- 100 9/3/16 1012 2

我正试图在SQL Server 2008数据库中想出一种方法,通过销售订单表获取零件的未结需求,按到期日订购,然后查看采购订单表,按采购订单完成销售订单,并按到期日订购采购订单供应。同时,我需要显示哪些采购订单正在履行销售订单

例如:

SO
表格

SO#     DueDate     Part Number  Required QTY
---------------------------------------------
100     9/3/16      1012          2
101     9/12/16     1012          1
107     10/11/16    1012          4
103     10/17/16    1012          7
PO
表格:

PO#     DueDate     Part Number  Ordered QTY
--------------------------------------------
331     9/1/16      1012          1
362     9/2/16      1012          1
359     9/24/16     1012          5
371     10/1/16     1012          3
380     10/10/16    1012          10
有了这些数据,我希望看到这样的结果:

SO#  DueDate     Part Number  Required QTY  PO number  QTY Used  QTY Remain
 --------------------------------------------------------------------------
100  9/3/16      1012          2             331         1         0 
100  9/3/16      1012          1             362         1         0
101  9/12/16     1012          1             359         1         4
107  10/11/16    1012          4             359         4         0
103  10/17/16    1012          7             371         3         0
103  10/17/16    1012          7             380         4         6
我以前做过这个销售订单履行流程,但并没有细分订单履行的订单,只是将所有未结供应相加,然后从每个销售订单中减去供应,以获得剩余供应的运行平衡


非常感谢您的帮助。

我发现了一个有点奇怪的解决方案,希望它能帮助您。也许以后我可以优化它,但现在我按原样发布:

;WITH cte AS (
    SELECT 1 as l
    UNION ALL
    SELECT l+1
    FROM cte
    WHERE l <= 1000000
), SO_cte AS (
    SELECT  *,
            ROW_NUMBER() OVER (ORDER BY DueDate ASC) as rn
    FROM SO s
    CROSS JOIN cte c
    WHERE c.l <= s.[Required QTY]
), PO_cte AS (
    SELECT  *,
            ROW_NUMBER() OVER (ORDER BY DueDate ASC) as rn
    FROM PO p
    CROSS JOIN cte c
    WHERE c.l <= p.[Ordered QTY]
), almost_done AS (
    SELECT DISTINCT     
            s.SO#,
            s.DueDate,
            s.[Part Number],
            p.PO#,
            s.[Required QTY],
            p.[Ordered QTY]
    FROM SO_cte s
    LEFT JOIN PO_cte p
        ON p.rn = s.rn
), final AS (
    SELECT  *,
            ROW_NUMBER() OVER (ORDER BY DueDate) AS RN
    FROM almost_done
)

SELECT  f.SO#,
        f.DueDate,
        f.[Part Number],
        f.[Required QTY],
        f.PO#,
        CASE WHEN f.[Ordered QTY]>f.[Required QTY] 
                THEN ISNULL(ABS(f1.[Required QTY]-f1.[Ordered QTY]),f.[Required QTY]) 
                ELSE f.[Ordered QTY] END 
                        as [QTY Used],
        f.[Ordered QTY] - 
        CASE WHEN f1.PO# = f.PO# 
                THEN f1.[Ordered QTY]
                ELSE
                    CASE WHEN f.[Ordered QTY]>f.[Required QTY] 
                            THEN ISNULL(ABS(f1.[Required QTY]-f1.[Ordered QTY]),f.[Required QTY]) 
                            ELSE f.[Ordered QTY] END
         END as [QTY Remain]
FROM final f
LEFT JOIN final f1
    ON f.RN = f1.RN+ 1
        AND (f.SO# = f1.SO# OR f.PO# = f1.PO#)
OPTION(MAXRECURSION 0)

输出表的逻辑,尤其是
Qty reside
不清楚。如果您想要答案,我建议您使用SQLFiddle.com来建立一个我们可以使用的示例。我将使用的方法是编写一个查询,将队列中的下一个“剩余”采购订单应用于队列中的下一个剩余销售订单,然后重新运行该查询,直到SO或PO用完为止。您需要一个工作表,该工作表可以对表进行快照并记录工作金额,还需要另一个表来记录最终金额。@AshwinNair所有输出
QTY
列都是一个运行总数。查看每一行,就好像采购订单已尽其所能满足要求一样,我们记录了使用了多少零件,如果采购订单中没有包含足够的零件,我们还需要多少零件,或者如果没有全部使用,我们还需要多少零件。下一行是下一个采购订单对不完整SO的影响,或者如果当前SO已完全满足,则下一个SO。您是否尝试过以下解决方案?奇怪的是:)@Clement首先它填充了订单的每一行,填充的次数与*Qty列中的相同,并按DueDate排序。然后,两个排序表通过行号连接,因此so中的每个1个数量与PO中的1个数量匹配,我们获取不同的值并将行号添加到该记录集中。然后,我们将此记录集与当前行和下一行(其中SO id或PO id相同)连接的记录集相匹配,并计算已使用的数量和剩余数量。。。事实上那是4年前的事了,伙计:)这是一个相当原始的解决方案f.e.CTE,有1000000行…@Clement你可以在这里查看,谢谢你的快速回复!
SO# DueDate     Part Number Required QTY    PO# QTY Used    QTY Remain
100 2016-09-03  1012        2               331 1           0
100 2016-09-03  1012        2               362 1           0
101 2016-09-12  1012        1               359 1           4
107 2016-10-11  1012        4               359 4           0
103 2016-10-17  1012        7               371 3           0
103 2016-10-17  1012        7               380 4           6