需要通过数量值向临时表分配值

时间:2018-10-17 08:00:46

标签: tsql sql-server-2008-r2

我有两个桌子

表A-订单项

M3

表B-纸箱标签

CONS_KEY | LINE_NO | ITEM_QTY
------------------------------
1084353  | 1       | 3
1084353  | 2       | 1
1084354  | 1       | 2
1084354  | 2       | 1
1084354  | 3       | 2

我需要创建一个临时表,并根据LINE_ITEM(和CONS_KEY)使用ITEM_QTY将LINE_NO分配给LABEL_ID。

表A中的第一个ITEM_QTY表示前三个LABEL_ID用于LINE_NO = 1,然后下一个LABEL_ID用于LINE_NO = 2(总共4个CONS_KEY = 1084353标签)

临时表-预期结果

CONS_KEY | LABEL_ID
-----------------------
1084353  | 717EXP00001
1084353  | 717EXP00002
1084353  | 717EXP00003
1084353  | 717EXP00004
1084354  | 718EXP00001
1084354  | 718EXP00002
1084354  | 718EXP00003
1084354  | 718EXP00004
1084354  | 718EXP00005

尽可能避免使用游标。 这篇文章给了我一个想法,我可能如何做,但不确定如何适应我的要求-Need to generate n rows based on a value in a column

1 个答案:

答案 0 :(得分:1)

由于两个表中都多次出现CONS_KEY列,因此您需要在此处添加一些技巧,这是用于连接它们的列。
第一个技巧是将row_number添加到表B中,这将为您每个cons_key的每个标签ID提供一个数字,第二个技巧是将dense_rank添加到表A和tally表的连接中将为您稍后在联接中使用的每一行提供一个数字。

首先,创建并填充示例表(在您将来的问题中为我们保存此步骤):

DECLARE @A AS TABLE
(
    CONS_KEY int,
    LINE_NO int,
    ITEM_QTY int
);

INSERT INTO @A (CONS_KEY, LINE_NO, ITEM_QTY) VALUES
(1084353, 1, 3),
(1084353, 2, 1),
(1084354, 1, 2),
(1084354, 2, 1),
(1084354, 3, 2);

DECLARE @B AS TABLE
(
    CONS_KEY int,
    LABEL_ID varchar(20)
);

INSERT INTO @B (CONS_KEY, LABEL_ID) VALUES
(1084353, '717EXP00001'),
(1084353, '717EXP00002'),
(1084353, '717EXP00003'),
(1084353, '717EXP00004'),
(1084354, '718EXP00001'),
(1084354, '718EXP00002'),
(1084354, '718EXP00003'),
(1084354, '718EXP00004'),
(1084354, '718EXP00005');

然后,就像您链接到的答案一样,使用数字表(在这种情况下,CTE称为Tally)-但您还需要另一个CTE来添加row_number-这就是称为B的CTE。

WITH Tally(n) AS
(
    SELECT TOP (select max(ITEM_QTY) from @A) ROW_NUMBER() OVER(ORDER BY @@SPID) 
    FROM sys.objects 
), A AS
(
SELECT  CONS_KEY, LINE_NO, ITEM_QTY,
        DENSE_RANK() OVER(PARTITION BY CONS_KEY ORDER BY LINE_NO, N) As DR
FROM @A
JOIN Tally 
    ON ITEM_QTY >= n

), B AS
(
    SELECT CONS_KEY, LABEL_ID,
            ROW_NUMBER() OVER(PARTITION BY CONS_KEY ORDER BY LABEL_ID) As RN
    FROM @B
)

SELECT  A.CONS_KEY, LABEL_ID, LINE_NO, ITEM_QTY
FROM A
JOIN B 
    ON A.CONS_KEY = B.CONS_KEY 
    AND A.DR = B.RN 
ORDER BY A.CONS_KEY, LINE_NO, RN

结果:

CONS_KEY    LABEL_ID        LINE_NO     ITEM_QTY
1084353     717EXP00001     1           3
1084353     717EXP00002     1           3
1084353     717EXP00003     1           3
1084353     717EXP00004     2           1
1084354     718EXP00001     1           2
1084354     718EXP00002     1           2
1084354     718EXP00003     2           1
1084354     718EXP00004     3           2
1084354     718EXP00005     3           2

与第一个版本的区别:

  1. 现在将提示CTE改进为仅所需的数字。
  2. 添加了一个名为A的新cte,其中有一个dense_rank列,其编号与cte row_number中的B列相同(这是原​​始名称所缺少的)版本)
  3. 在结果中包含ITEM_QTY列,以便更轻松地查看结果是否正确。