【问题标题】:How to use while loop in Outer Apply - SQL Server如何在外部应用中使用 while 循环 - SQL Server
【发布时间】:2017-03-13 01:25:54
【问题描述】:

我需要做什么:

  • 根据最早的截止日期从销售订单中识别每个零件的未完成工作
  • 条件:列出满足销售订单需求的最早工作/工作(针对特定零件)。如果顶部工作不满足所需数量,则选择下一个工作..

销售订单表 - 名称:SalesOrder

SO   | Part    |    SO_Qty   |
--------------------------
SO1  | Part1   |    5   |
SO2  | Part2   |    7   |
SO3  | Part3   |    4   |

工作订单表 - 名称:JobOrder -((所有空缺工作 - 按 Due_Date 排序)

SO  | Part  | JO   | JO_Qty | Due_Date |
-----------------------------------------
SO1 | Part1 | JO1a |    6   | 11/01/16 |
SO1 | Part1 | JO1b |    5   | 11/10/16 |
SO2 | Part2 | JO2a |    3   | 11/01/16 |
SO2 | Part2 | JO2b |    2   | 11/08/16 |
SO2 | Part2 | JO2c |    9   | 11/18/16 |
SO3 | Part3 | JO3a |    4   | 12/05/16 |
SO3 | Part3 | JO3b |    2   | 12/20/16 |

结果表(这是我想看到的……)

SO  | Part  | SO_Qty | JO   | JO_Qty | Due_Date |
-------------------------------------------------
SO1 | Part1 |   5    | JO1a |   6    | 11/01/16 |
SO2 | Part2 |   7    | JO2a |   3    | 11/01/16 |
SO2 | Part2 |   7    | JO2b |   2    | 11/08/16 |
SO2 | Part2 |   7    | JO2c |   9    | 11/18/16 |
SO3 | Part3 |   4    | JO3a |   4    | 12/05/16 |

我尝试过的:

 Select OD.*, SQ.jo, SQ.jo_qty, SQ.due_date
 From SalesOrder AS OD
 OUTER APPLY (Select jo, jo_qty, due_date
              From JobOrder as JO   
              Where JO.so = OD.so AND JO.part = OD.part) AS SQ

这将返回所有匹配的工作订单,而不管工作订单数量。那不是我要找的……

我的问题:我可以在子查询中使用 while 循环来过滤记录吗?

提前感谢您的所有帮助..

您可以使用的脚本:

;WITH SalesOrder AS (
SELECT *
FROM (VALUES
('SO1', 'Part1', 5),
('SO2', 'Part2', 7),
('SO3', 'Part3', 4)
) as t(SO, Part, SO_Qty)
), JobOrder AS (
SELECT *
FROM (VALUES
('SO1', 'Part1', 'JO1a', 6 , '11/01/16'),
('SO1', 'Part1', 'JO1b', 5 , '11/10/16'),
('SO2', 'Part2', 'JO2a', 3 , '11/01/16'),
('SO2', 'Part2', 'JO2b', 2 , '11/08/16'),
('SO2', 'Part2', 'JO2c', 9 , '11/18/16'),
('SO3', 'Part3', 'JO3a', 4 , '12/05/16'),
('SO3', 'Part3', 'JO3b', 2 , '12/20/16')
) as t(SO, Part, JO, JO_Qty, Due_Date)
)

【问题讨论】:

  • 这个输出在结果表中是否有效SO2| Part2| 7| JO2c| 9| 11/18/16|
  • 是的。 Part2 SO_qty = 7 的需求。前 2 个工作的总数量 = 5。需要选择下一个工作以满足 SO 需求。谢谢
  • 使用 SQL Server 2012 及更高版本很容易。在 2008 年,我建议将光标放在自联接上。

标签: sql-server sql-server-2008 tsql


【解决方案1】:

我认为您可以使用递归 CTE 来解决它 - 它有点啰嗦,但这是我的最大努力...

WITH j AS
(
    SELECT
     jo.SO
    ,so.Part
    ,so.SO_Qty
    ,jo.JO
    ,jo.JO_Qty
    ,jo.Due_Date
    ,ROW_NUMBER() OVER(ORDER BY jo.SO, Due_Date) AS RowID
    FROM #jobOrder jo
    JOIN #SalesOrder so
    ON jo.SO = so.SO
    AND jo.Part = so.Part
)
,rCTE AS
(
    SELECT
     RowID
    ,SO
    ,Part
    ,SO_Qty
    ,JO
    ,JO_Qty
    ,Due_Date
    ,JO_Qty - SO_Qty AS Diff
    FROM j
    WHERE RowID = 1

    UNION ALL

    SELECT
     j.RowID
    ,r.SO
    ,j.Part
    ,j.SO_Qty
    ,j.JO
    ,j.JO_Qty
    ,j.Due_Date
    ,CASE   WHEN j.Part != r.Part OR (j.Part = r.Part AND Diff < 0) THEN
                j.JO_Qty - j.SO_Qty
            END
    FROM rCTE r
    JOIN j
    ON j.RowID = r.RowID + 1
)
SELECT
 *
FROM rCTE
WHERE Diff IS NOT NULL;

【讨论】:

  • 非常感谢..我会试试这个并更新你。
  • @Hycinth,这有帮助吗?
  • HotblackDesiato
  • HotblackDesiato,还没有。我仍在努力。您的解决方案很棒,但它在相同的 SO 下返回结果。 (SO1)。不区分销售订单。此外,我对这个 CTE 仍然不太了解,并试图理解逻辑而不只是抓住代码。谢谢你没有忘记我..
猜你喜欢
  • 2013-08-18
  • 1970-01-01
  • 2020-03-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 2018-10-28
  • 1970-01-01
  • 2015-03-11
相关资源
最近更新 更多