【发布时间】:2014-05-18 20:43:49
【问题描述】:
我正在使用 SQL Server 2008 并正在寻找一个可以根据数量复制记录的查询
表有 QTY 和 PartNumber 列。需要为每个 QTY 添加额外的记录。 因此,假设零件编号的数量为 3。我需要三行包含该零件编号。
任何帮助将不胜感激。谢谢。
【问题讨论】:
标签: sql-server sql-server-2008
我正在使用 SQL Server 2008 并正在寻找一个可以根据数量复制记录的查询
表有 QTY 和 PartNumber 列。需要为每个 QTY 添加额外的记录。 因此,假设零件编号的数量为 3。我需要三行包含该零件编号。
任何帮助将不胜感激。谢谢。
【问题讨论】:
标签: sql-server sql-server-2008
测试数据
CREATE TABLE Test_Table
(
PartNumber VARCHAR(20) ,
Quantity INT,
[Description] VARCHAR(20),
Category VARCHAR(20),
Size VARCHAR(20),
Tags VARCHAR(20)
)
GO
INSERT INTO Test_Table
VALUES
('Part 100', 3, 'Description 100', 'Cat100', 'Size100', 'Tag100'),
('Part 101', 2,'Description 101', 'Cat101', 'Size101', 'Tag101')
GO
查询
;WITH CTE (Vals)
AS (
SELECT 1
UNION ALL
SELECT 1 + Vals
FROM CTE WHERE Vals < 99
)
SELECT A.PartNumber
, 1 AS QTY
,A.Category
,A.[Description]
,A.Size
,A.Tags
FROM Test_Table A
INNER JOIN CTE C ON C.Vals <= A.Quantity
ORDER BY A.PartNumber
结果集
╔════════════╦═════╦══════════╦═════════════════╦═════════╦════════╗
║ PartNumber ║ QTY ║ Category ║ Description ║ Size ║ Tags ║
╠════════════╬═════╬══════════╬═════════════════╬═════════╬════════╣
║ Part 100 ║ 1 ║ Cat100 ║ Description 100 ║ Size100 ║ Tag100 ║
║ Part 100 ║ 1 ║ Cat100 ║ Description 100 ║ Size100 ║ Tag100 ║
║ Part 100 ║ 1 ║ Cat100 ║ Description 100 ║ Size100 ║ Tag100 ║
║ Part 101 ║ 1 ║ Cat101 ║ Description 101 ║ Size101 ║ Tag101 ║
║ Part 101 ║ 1 ║ Cat101 ║ Description 101 ║ Size101 ║ Tag101 ║
╚════════════╩═════╩══════════╩═════════════════╩═════════╩════════╝
【讨论】:
如果您的数量超过 MAXRECURSION,您可以切换到不同的数字生成子查询
With B (N) AS (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL
SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL
SELECT 8 UNION ALL SELECT 9
), C (N) AS (
SELECT b.N + t.N*10 + h.N*100
FROM b
CROSS JOIN b t
CROSS JOIN b h
)
SELECT A.PartNumber
, 1 AS QTY
, A.Category
, A.[Description]
, A.Size
, A.Tags
, A.Sheet
, A.Room
FROM Test_Table A
INNER JOIN C ON C.n <= A.QTY
ORDER BY A.PartNumber
如果您的基表有很多行,更好的方法是创建一个临时或永久表来存储数字生成器的结果,然后将该表连接到基表。
WITH B (N) AS (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL
SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL
SELECT 8 UNION ALL SELECT 9
)
SELECT b.N + t.N*10 N
INTO #number
FROM b
CROSS JOIN b t
CROSS JOIN b h
GO
SELECT A.PartNumber
, 1 AS QTY
, A.Category
, A.[Description]
, A.Size
, A.Tags
, A.Sheet
, A.Room
FROM Test_Table A
INNER JOIN #number ON #number.N <= A.QTY
ORDER BY A.PartNumber
【讨论】:
我也想做同样的事情,为了让函数更有用,我根据代码示例创建了一个表函数:
CREATE FUNCTION dbo.tfn_all_ints(@max_val integer)
RETURNS @retTable TABLE
(
val INT
)
BEGIN
/* returns @max_val rows with Vals 1 to @max_val */
/* limited to 99 because of the recursion limit */
WITH CTE (Vals)
AS (
SELECT 1
UNION ALL
SELECT 1 + Vals
FROM CTE WHERE Vals < 99
)
INSERT INTO @retTable(val)
SELECT Vals
FROM CTE C
WHERE Vals <= @max_val
RETURN
END
调用示例: SELECT * FROM tfn_all_ints(2)
【讨论】: