复制列中的所有数字并将其粘贴到ID值为1的行中

时间:2018-06-15 09:02:57

标签: sql sql-server

我想要一个SQL查询来复制一个列,并将其粘贴到较小的ID 1。 (参见下面的示例)由于系统限制,我只能在SQL查询中执行此操作。 SQL擅长这样的计算吗?

示例输入

[id] [old]
1    11
2    13
3    14
4    15
6    17
7    18
10   20

示例输出

[id] [old] [new]
0    null  11     (new row of id 0 created, for placing 11)
1    11    13
2    13    14
3    14    15
4    15    null   
5    null  17     (new row of id 5 created, for placing 17)
6    17    18
7    18    null
9    null  20
10   20    null

2 个答案:

答案 0 :(得分:2)

首先创建缺失记录,然后针对以下记录进行更新。

IF OBJECT_ID('tempdb..#AvailableIDs') IS NOT NULL
    DROP TABLE #AvailableIDs

CREATE TABLE #AvailableIDs (ID INT, OldID INT)

INSERT INTO #AvailableIDs (
    ID,
    OldID)
VALUES
    (1, 11),
    (2, 13),
    (3, 14),
    (4, 15),
    (6, 17),
    (7, 18),
    (10, 20)


INSERT INTO #AvailableIDs (
    ID)
SELECT
    ID = ID - 1
FROM
    #AvailableIDs AS A
WHERE
    NOT EXISTS (SELECT 1 FROM #AvailableIDs AS X WHERE X.ID = A.ID - 1)


UPDATE A SET
    OldID = X.OldID
FROM
    #AvailableIDs AS A
    LEFT JOIN #AvailableIDs AS X ON A.ID = X.ID - 1


SELECT A.ID, UpdatedID = A.OldID FROM #AvailableIDs AS A ORDER BY 1

结果:

ID  UpdatedID
0   11
1   13
2   14
3   15
4   NULL
5   17
6   18
7   NULL
9   20
10  NULL

答案 1 :(得分:-1)

您可以使用非常基本的查询解决此问题,而无需使用辅助表(或更新):

with ids as (
      select id
      from t
      union -- on purpose to remove duplicates
      select id - 1
      from t
     )
select ids.id, t.old, lead(t.old) over (order by ids.id)
from ids left join
     t
     on t.id = ids.id;

这是显示结果的rextester

这是另一个没有join的版本:

with t as (
      select *
      from (values (1, 11), (2, 13), (3, 14), (4, 15), (6, 17), (7, 18), (10, 20)
           ) v(id, old)
     ),
     ids as (
      select id, old, null as new
      from t
      union all
      select id - 1, null as old, old as new
      from t
     )
select ids.id, min(old) as old, min(new) as new
from ids 
group by ids.id;