SQL选择X行并插入新行

时间:2019-06-20 15:34:34

标签: sql sql-server

我正在尝试将一堆数据从一个旧数据库迁移到一个新数据库,旧数据库过去只具有在单行中发生的警报数量。新数据库为发生的每个警报插入一条新记录。这是它外观的基本版本。我想从表1中选择每一行,并将警报值的数目作为新行插入表2中。

表1:

|  Alarm ID    |  Alarm Value   |
|--------------|----------------|
|     1        |        3       |
|     2        |        2       |

应作为以下值进入警报表。

表2:

| Alarm New ID |  Value   |
|--------------|----------|
|     1        |    1     |
|     2        |    1     |
|     3        |    1     |
|     4        |    2     |
|     5        |    2     |

我想创建一个选择插入脚本来执行此操作,因此select语句将带回出现在“值”列中的行数。

3 个答案:

答案 0 :(得分:4)

递归CTE为此很方便:

with cte as (
      select id, alarm, 1 as n
      from t
      union all
      select id, alarm, n + 1
      from cte
      where n < alarm
     )
select row_number() over (order by id) as alarm_id, id as value
from cte
order by 1
option (maxrecursion 0);

注意:如果您的值不超过100,则可以删除OPTION (MAXRECURSION 0)

答案 1 :(得分:0)

使用CTE复制值。

DECLARE @T TABLE(AlarmID INT, Value INT)
INSERT @T VALUES
(1,3),
(2,2)

;WITH ReplicateAmount AS
 (
    SELECT  AlarmID, Value FROM @T

    UNION ALL

    SELECT R.AlarmID, Value=(R.Value - 1)
    FROM ReplicateAmount R 
    INNER JOIN @T T ON R.AlarmID = T.AlarmID
    WHERE R.Value > 1
)

SELECT 
    AlarmID = ROW_NUMBER() OVER( ORDER BY AlarmID), 
    Value = AlarmID --??
FROM
    ReplicateAmount 
ORDER BY 
    AlarmID

这回答了您的问题。我认为下面的查询会更有用,但是,您不包括使用情况上下文。

SELECT 
    AlarmID,
    Value 
FROM
    ReplicateAmount 
ORDER BY 
    AlarmID

答案 2 :(得分:0)

您可以使用Tally表,而不是使用递归的rCTE(顾名思义)并在100行时失败,您可以使用Tally表,该表也往往更快:

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1, N N2, N N3)
SELECT ROW_NUMBER() OVER (ORDER BY V.AlarmID,T.I) AS AlarmNewID,
       V.AlarmID
FROM (VALUES(1,3),(2,2))V(AlarmID,AlarmValue)
     JOIN Tally T ON V.AlarmValue >= T.I;