关于sql:根据另一个表中的列的值生成行 | 珊瑚贝

Generating Lines based on a value from a column in another table


我有下表:

1
EventID=00002,DocumentID=0005,EventDesc=ItemsReceived

我在另一个表中有数量

1
DocumentID=0005,Qty=20

我想生成一个包含 20 行的结果(取决于数量),并带有一个自动生成的列,该列将具有以下序列:

1
2
3
4
5
6
ITEM_TAG_001,
ITEM_TAG_002,
ITEM_TAG_003,
ITEM_TAG_004,
..
ITEM_TAG_020

最好是介绍一个数字表,很多地方都很帅…

一些东西:

创建一些测试数据:

1
2
3
4
5
6
7
DECLARE @MockNumbers TABLE(NUMBER BIGINT);
DECLARE @YourTable1 TABLE(DocumentID INT,ItemTag VARCHAR(100),SomeText VARCHAR(100));
DECLARE @YourTable2 TABLE(DocumentID INT, Qty INT);

INSERT INTO @MockNumbers SELECT TOP 100 ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values;
INSERT INTO @YourTable1 VALUES(1,‘FirstItem’,‘qty 5’),(2,‘SecondItem’,‘qty 7’);
INSERT INTO @YourTable2 VALUES(1,5),                     (2,7);

–查询

1
2
3
4
SELECT CONCAT(t1.ItemTag,‘_’,REPLACE(STR(A.Number,3),‘ ‘,‘0’))
FROM @YourTable1 t1
INNER JOIN @YourTable2 t2 ON t1.DocumentID=t2.DocumentID
CROSS APPLY(SELECT NUMBER FROM @MockNumbers WHERE NUMBER BETWEEN 1 AND t2.Qty) A;

结果

1
2
3
4
5
6
7
8
FirstItem_001
FirstItem_002
[]
FirstItem_005
SecondItem_001
SecondItem_002
[]
SecondItem_007

简而言之:

我们使用 INNER JOIN 来获取加入到项目的数量。

现在我们使用 APPLY,这是一个逐行操作,可以根据需要将尽可能多的行绑定到集合。

第一项将返回 5 行,第二项返回 7 行。STR() 和 REPLACE() 的技巧是创建填充数字的一种方法。您可能会使用 FORMAT() (v2012 ),但这工作相当缓慢…

表 @MockNumbers 是一个声明的表变量,其中包含从 1 到 100 的数字列表。这个答案提供了一个如何创建物理数字和日期表的示例。任何数据库都应该有这样的表…

如果您不想创建数字表,您可以搜索计数表或即时计数。有很多答案显示了如何创建运行数字列表的方法…a


这是你的 sql 查询。

1
2
3
4
5
6
7
8
WITH cte AS (
    SELECT 1 AS ctr, t2.Qty, t1.EventID, t1.DocumentId, t1.EventDesc FROM tableA t1  
    INNER JOIN tableB t2 ON t2.DocumentId = t1.DocumentId      
    UNION ALL
    SELECT ctr + 1, Qty, EventID, DocumentId, EventDesc  FROM cte
    WHERE ctr <= Qty
)SELECT *, concat(‘ITEM_TAG_’, RIGHT(‘000’+ CAST(ctr AS VARCHAR(3)),3)) FROM cte
OPTION (maxrecursion 0);

输出:


enter

  • 使用 ctr <= Qty 将一步一步计算…而不是使用 ctr < Qty
  • 谢谢@Shnugo,但我开始@ ctr = 1


来源:https://www.codenong.com/58056964/

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?