如何根据行的值创建循环?

时间:2014-11-27 08:23:21

标签: sql sql-server tsql loops cursor

当我使用下面的查询在光标内部循环时,我遇到了问题。

table1中的

数据将如下所示:

id  |  data
----|---------
A   |  4
B   |  2
C   |  5

table2中的结果应该是这样的:

id  |  data
----|---------
A   |  1
A   |  1
A   |  1
A   |  1
B   |  1
B   |  1
C   |  1
C   |  1
C   |  1
C   |  1
C   |  1

我有光标的SQL查询,如下所示:

DECLARE @table2 table ( id VARCHAR(500), data INTEGER)

DECLARE Cur CURSOR FOR
SELECT id, data FROM table1

OPEN Cur 

WHILE ( @@FETCH_STATUS = 0 )
    BEGIN
        DECLARE @LoopNum INTEGER
        DECLARE @tempID VARCHAR(255)
        DECLARE @tempDATA INTEGER

        FETCH NEXT FROM Cur INTO @tempID, @tempDATA

        set @LoopNum = 0

        WHILE @LoopNum < @tempDATA
            BEGIN
            INSERT INTO table2 (id, data)
            VALUES( @tempID, 1)
            SET @LoopNum = @LoopNum + 1
        END
    END

CLOSE Cur 
DEALLOCATE Cur 

SELECT * FROM table2

但查询无效。我的查询有问题吗? 谢谢。

4 个答案:

答案 0 :(得分:3)

将此查询用于预期结果。

CREATE TABLE #test
  (id   CHAR(1),data INT)

INSERT #test VALUES ('A',4)
INSERT #test VALUES('B',2)
INSERT #test VALUES('C',5);


SELECT s.id, 1 AS data
FROM #test s
INNER JOIN 
master.dbo.spt_values t ON t.type='P'
   AND t.number BETWEEN 1 AND s.data

注意:请参阅此 Why (and how) to split column using master..spt_values?

答案 1 :(得分:1)

你实际上不需要循环

IF OBJECT_ID('TEMPDB..#TEMP') IS NOT NULL 
   DROP TABLE #TEMP


SELECT 'A' AS ID, 4 AS DATA
INTO #TEMP UNION
SELECT 'B', 2 UNION
SELECT 'C', 5

;WITH CTE AS 
(
     SELECT 1 AS NUMBER
     UNION ALL
     SELECT NUMBER + 1
     FROM CTE
     WHERE NUMBER < 100
)
SELECT T.ID, 1
FROM   CTE C
INNER JOIN #TEMP T
ON C.NUMBER <= T.DATA
ORDER BY T.ID

小心如果你想在CTE中生成一大组数字,它可能会变慢。

答案 2 :(得分:0)

使用Recursive CTE来帮助您循环播放记录。

CREATE TABLE #test
  (id   CHAR(1),data INT)

INSERT #test
VALUES ('A',4),('B',2),('C',5);

WITH cte
     AS (SELECT 1 AS da,id,data
         FROM   #test a
         UNION ALL
         SELECT da + 1,id,data
         FROM   cte a
         WHERE  da < (SELECT data
                      FROM   #test b
                      WHERE  a.id = b.id))
SELECT id,
       1 AS data
FROM   cte
ORDER  BY id 

答案 3 :(得分:0)

我使用了两个循环 1.每排 2.对于重复插入的编号

SET NOCOUNT on;
DECLARE @t table(row int IDENTITY(1,1),id varchar(10),data int)
INSERT INTO @t
SELECT * from xyz

DECLARE @x table(id varchar(10),data int)  --table to hold the new data
DECLARE @i int=(SELECT count (*) from xyz)  --number of rows main table
DECLARE @y int   --number of duplicate
DECLARE @p int=1  --number of rows
WHILE @i!=0  --loop until last row of main table
BEGIN 
SET @y=(SELECT data FROM @t WHERE row=@p)  --set @y for number of 'row duplicate'
WHILE @y!=0
BEGIN 
INSERT INTO @x 
SELECT id,1
FROM @t 
WHERE row=@p
SET @y=@y-1
END 
SET @p=@p+1
SET @i=@i-1
END 
SELECT * FROM @x

enter image description here