繁体   English   中英

从表 A 到表 B 返回值

[英]Return values from Table A to Table B

我需要帮助。 大家好,我有 2 个表,如果 RunningTotalQtyReceive(来自表 A)>= RunningTotalQtyShort(来自表 B),我想将表 A 中的FIRST DueDate 和 QtyReceive 返回到表 B。 如果 QtyReceive/TotalRunningQtyReceive 无法覆盖 QtyShort/TotalRunningQtyShort,则返回 NULL。 数据集已按日期排序。 RunningTotalQtyReceiveRunningTotalQtyShort由 Window Function 计算得出。

SUM(QtyReceive) OVER(PARTITION BY Item ORDER BY DueDate)
SUM(QtyShort) OVER(PARTITION BY Item ORDER BY MatlDueDate)

表 A:

Item     DueDate         QtyReceive   RunningTotalQtyReceive
 A1     2021-10-08            6                6
 A1     2021-10-22            5                11
 A1     2022-02-01            9                20

表 B:

Item    MatlDueDate     QtyShort    RunningTotalQtyShort
 A1      2022-06-01        0                0
 A1      2022-06-03        1                1
 A1      2022-06-04        2                3
 A1      2022-06-05        4                7
 A1      2022-06-06        8                15
 A1      2022-06-07        5                20
 A1      2022-06-08        3                23
 A1      2022-06-09        10               33

预期 Output:

Item    MatlDueDate QtyShort    RunningTotalQtyShort    RunningTotalQtyReceive  DueDate    QtyReceive
 A1     2022-06-01     0                 0                       6             2021-10-08      6
 A1     2022-06-03     1                 1                       6             2021-10-08      6
 A1     2022-06-04     2                 3                       6             2021-10-08      6
 A1     2022-06-05     4                 7                       11            2021-10-22      5
 A1     2022-06-06     8                 15                      20            2022-02-01      9
 A1     2022-06-07     5                 20                      20            2022-02-01      9
 A1     2022-06-08     3                 23                      NULL            NULL          NULL
 A1     2022-06-09     10                33                      NULL              NULL        NULL

这是我返回预期 output 的脚本:

SELECT 
     b.*, 
     c.RunningTotalQTyReceive, 
     c.DueDate, 
     c.QtyReceive
FROM TableB b 
OUTER APPLY (SELECT TOP 1 
                a.RunningTotalQTyReceive,
                FIRST_VALUE(DueDate) OVER(ORDER BY DueDate) AS DueDate, 
                a.QtyReceive
             FROM TableA a
             WHERE a.item = b.item
             AND a.RunningTotalQtyReceive >= b.RunningTotalQtyShort
             ) c

问题是这是“三角形”连接( https://www.sqlservercentral.com/articles/hidden-rbar-triangular-joins#:~:text=A%20Triangular%20Join%20is%20nothing,rows%20spawned% 20are%20nearly%20trivial ) 会减慢查询执行时间。 我用了 35 分钟到 1 小时完成了 200,000 行数据集的执行。 你能帮我想办法减少执行时间吗? 任何其他联接或用户定义的函数? 十分感谢。 任何帮助将不胜感激。 如果您需要对我的问题进行任何澄清,请告诉我。

创建表A:

CREATE TABLE TableA
(
Item varchar(2),
DueDate date,
QtyReceive int,
RunningTotalQtyReceive int
);

INSERT INTO TableA values
('A1',      '10/08/2021',       6,       6),
('A1',      '10/22/2021',       5,      11),
('A1',      '02/01/2022',       9,      20);

创建表B:

CREATE TABLE TableB
(
Item varchar(2),
MatlDueDate date,   
QtyShort int,
RunningTotalQtyShort int,
);

INSERT INTO TableB values
('A1',      '06/01/2022',         0,         0),
('A1',      '06/03/2022',         1,         1),
('A1',      '06/04/2022',         2,         3),
('A1',      '06/05/2022',         4,         7),
('A1',      '06/06/2022',         8,         15),
('A1',      '06/07/2022',         5,         20),
('A1',      '06/08/2022',         3,         23),
('A1',      '06/09/2022',         10,        33);

您不需要存储 RunningTotalQtyReceive 和 RunningTotalQtyShort 的值,因为它们可以从输入表中计算出来。 尝试以下操作以获得所需的结果:

With CTE1 AS
(
  Select Item, DueDate, QtyReceive,  
         SUM(QtyReceive) OVER(PARTITION BY Item ORDER BY DueDate) AS RunningTotalQtyReceive
  From TableA
),
CTE2 AS
(
 Select Item, MatlDueDate, QtyShort,
        SUM(QtyShort) OVER(PARTITION BY Item ORDER BY MatlDueDate) AS RunningTotalQtyShort
 From TableB
)

Select B.Item, B.MatlDueDate, B.QtyShort, B.RunningTotalQtyShort,
       A.RunningTotalQtyReceive, A.DueDate, A.QtyReceive
From CTE2 B
Left Join
(
  Select Item, DueDate, QtyReceive, RunningTotalQtyReceive, 
         LAG(RunningTotalQtyReceive, 1, 0) Over (Partition By Item Order By DueDate) AS lrtqr
  From CTE1
) A

On B.RunningTotalQtyShort <=  A.RunningTotalQtyReceive and B.RunningTotalQtyShort >=  A.lrtqr
And B.Item = A.Item

查看db<>fiddle的演示。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM