【问题标题】:How to Join tables to assign one record to multiple records in a "FIFO" order如何联接表以按“FIFO”顺序将一条记录分配给多条记录
【发布时间】:2015-12-17 07:11:36
【问题描述】:

我正在尝试将一张表中的多条记录分配给第二张表中的单条记录,直到达到数量为止。我正在使用 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 |
+-------------+------+------+-------------+----------+----------+

内部发票

+------------+----------+------+------+-----+----------+
| 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 中的前两条记录分配给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

这就是我得到的。我尝试了很多不同的方法,但看起来我现在被卡住了。任何帮助表示赞赏。

对不起,图片链接,我似乎还没有直接链接图片的声誉。当我获得足够的代表时,我会将它们改回来。

【问题讨论】:

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


    【解决方案1】:

    计算Qty 的运行总和,以了解从ExtInvoice 跳过多少行

    SUM(Qty) OVER (PARTITION BY P_No ORDER BY NumOrder)
    

    使用OUTER APPLY 连接表并选择QtyTOP 中定义的行数。

    样本数据

    我又添加了一个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);
    

    查询

    最后一个查询你应该列出实际的列名而不是*。 为了使它有效地工作,(P_No, NumOrder) 上的ExtInvoice 表应该有一个索引。

    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        |
    +------------+----------+------+------+-----+----------+--------+-------------+------+------+-------------+----------+----------+
    

    SQL Fiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-14
      • 2017-02-24
      • 2019-02-18
      相关资源
      最近更新 更多