我尝试将一个表中的多个记录分配给第二个表中的单个记录,直到达到数量。我正在使用MS SQL 2012。
我们有这个外部发票表
ExtInvoice
+-------------+------+------+-------------+----------+----------+
| Ext_Invoice | P_No | Part | InvoiceDate | Due_Date | NumOrder |
+-------------+------+------+-------------+----------+----------+
| 571 | 607 | 7991 | 151116 | 151222 | 1 |
| 572 | 607 | 7991 | 151120 | 151228 | 2 |
| 573 | 607 | 7991 | 151127 | 160104 | 3 |
+-------------+------+------+-------------+----------+----------+
InternalInvoice
+------------+----------+------+------+-----+----------+
| Invoice_No | Original | P_No | Part | Qty | NumOrder |
+------------+----------+------+------+-----+----------+
| 198 | 607 | 607 | 7991 | 2 | 1 |
| 199 | RE607 | 607 | 7991 | 1 | 2 |
| 200 | RE607 | 607 | 7991 | 1 | 3 |
+------------+----------+------+------+-----+----------+
结果是将ExtInvoice
中的前2个记录分配到InternalInvoice
中的第一个记录,其余记录应转到第二个InternalInvoice
记录。 ExtInvoice
中的每一行代表一个Quantity
。
NumOrder
不是唯一的,因为这是ROW_Number
SQL计算。
所需的结果是:
表中显然有更多的发票,但这是它无法正常工作的部分。有一些带有row_number()操作的临时表来访问表ExtInvoice,InternalInvoice。我实际上使用了这个thread
我目前正在使用
SELECT *
FROM InternalInvoice AS R
JOIN ExtInvoice AS S
ON S.P_No=R.P_No
AND S.Part=R.Part
AND R.Qty>=S.NumOrder
这就是我所得到的。我尝试了很多不同的方法,但看起来我现在被卡住了。任何帮助表示赞赏。
对不起图片链接,似乎我还没有直接链接图片的声誉。当我得到足够的代表时,我会改回来。
答案 0 :(得分:1)
计算Qty
的运行总和,以了解要使用
ExtInvoice
跳过多少行
SUM(Qty) OVER (PARTITION BY P_No ORDER BY NumOrder)
使用OUTER APPLY
连接表格并选择Qty
中TOP
定义的行数。
示例数据
我又添加了一个P_No
来验证结果是否已正确分区。
DECLARE @ExtInvoice TABLE
(Ext_Invoice int, P_No int, Part int, InvoiceDate int, Due_Date int, NumOrder int);
INSERT INTO @ExtInvoice
(Ext_Invoice, P_No, Part, InvoiceDate, Due_Date, NumOrder)
VALUES
(571, 607, 7991, 151116, 151222, 1),
(572, 607, 7991, 151120, 151228, 2),
(573, 607, 7991, 151127, 160104, 3),
(574, 608, 7991, 151127, 160104, 1);
DECLARE @InternalInvoice TABLE
(Invoice_No int, Original varchar(5), P_No int, Part int, Qty int, NumOrder int);
INSERT INTO @InternalInvoice
(Invoice_No, Original, P_No, Part, Qty, NumOrder)
VALUES
(198, '607', 607, 7991, 2, 1),
(199, 'RE607', 607, 7991, 1, 2),
(200, 'RE607', 607, 7991, 1, 3),
(201, 'RE608', 608, 7991, 1, 1);
<强>查询强>
我是最终查询,您应该列出实际的列名而不是*
。
为了使其有效工作,ExtInvoice
上的(P_No, NumOrder)
表应该有一个索引。
WITH
CTE_InternalInvoices
AS
(
SELECT
I.*
,SUM(Qty) OVER (PARTITION BY P_No ORDER BY NumOrder) AS SumQty
FROM
@InternalInvoice AS I
)
SELECT
*
FROM
CTE_InternalInvoices
OUTER APPLY
(
SELECT TOP(CTE_InternalInvoices.Qty) *
FROM @ExtInvoice AS E
WHERE
E.P_No = CTE_InternalInvoices.P_No
AND E.NumOrder > CTE_InternalInvoices.SumQty - CTE_InternalInvoices.Qty
ORDER BY E.NumOrder
) AS CA
ORDER BY CTE_InternalInvoices.Invoice_No;
<强>结果强>
+------------+----------+------+------+-----+----------+--------+-------------+------+------+-------------+----------+----------+
| Invoice_No | Original | P_No | Part | Qty | NumOrder | SumQty | Ext_Invoice | P_No | Part | InvoiceDate | Due_Date | NumOrder |
+------------+----------+------+------+-----+----------+--------+-------------+------+------+-------------+----------+----------+
| 198 | 607 | 607 | 7991 | 2 | 1 | 2 | 571 | 607 | 7991 | 151116 | 151222 | 1 |
| 198 | 607 | 607 | 7991 | 2 | 1 | 2 | 572 | 607 | 7991 | 151120 | 151228 | 2 |
| 199 | RE607 | 607 | 7991 | 1 | 2 | 3 | 573 | 607 | 7991 | 151127 | 160104 | 3 |
| 200 | RE607 | 607 | 7991 | 1 | 3 | 4 | NULL | NULL | NULL | NULL | NULL | NULL |
| 201 | RE608 | 608 | 7991 | 1 | 1 | 1 | 574 | 608 | 7991 | 151127 | 160104 | 1 |
+------------+----------+------+------+-----+----------+--------+-------------+------+------+-------------+----------+----------+