更新同一主键中的值
Update Value in same Primary Key
我正在尝试更新同一主键中的值,其中第一行值将应用于第二个序列,直到具有主键值的序列结束。
这是我的示例场景
这应该是预期的输出。
我不想更新已经有值的行。这可能吗?
我不知道如何实现这个输出。谁能帮我?我正在使用 SQL.
谢谢
您可以使用 window 函数和可更新的 CTE。
如果每个 id
只有一个非 null
值,则 window 最小值或最大值就足够了:
with cte as (
select value, min(value) over(partition by id) as new_value
from mytable t
)
update cte set value = new_value where value is null
如果您特别想要 sequence
具有值 1
的行,请使用条件 window 聚合:
with cte as (
select value,
min(case when sequence = 1 then value end) over(partition by id) as new_value
from mytable t
)
update cte set value = new_value where value is null
最后,如果您想要具有最小值 sequence
的行,而不考虑其实际值:
with cte as (
select value,
first_value(value) over(partition by id order by sequence) as new_value
from mytable t
)
update cte set value = new_value where value is null
DENSE_RANK 窗口函数对于此类序列很方便。如果目标只是 return 的值,则不需要存储它,因为它可以直接在 select.
中获取
DECLARE @Test as Table (
Id char(1),
Seq int,
Val varchar(10)
)
INSERT @Test (Id, Seq)
VALUES
('A','1'),
('A','2'),
('A','3'),
('A','4'),
('A','5'),
('B','1'),
('B','2'),
('B','3'),
('B','4'),
('C','4'),
('C','5');
-- Select Only
SELECT Id, Seq,
'Test' + LTRIM(STR(DENSE_RANK() OVER (ORDER BY Id))) as [Val]
FROM @Test
-- Update via derived table
UPDATE t
SET Val = 'Test' + LTRIM(STR(Seq2))
FROM @Test t
INNER JOIN (
SELECT Id, Seq, DENSE_RANK() OVER (ORDER BY Id) as [Seq2]
FROM @Test
) v
ON v.Id = t.Id AND v.Seq = t.Seq
我正在尝试更新同一主键中的值,其中第一行值将应用于第二个序列,直到具有主键值的序列结束。
这是我的示例场景
这应该是预期的输出。
我不想更新已经有值的行。这可能吗? 我不知道如何实现这个输出。谁能帮我?我正在使用 SQL.
谢谢
您可以使用 window 函数和可更新的 CTE。
如果每个 id
只有一个非 null
值,则 window 最小值或最大值就足够了:
with cte as (
select value, min(value) over(partition by id) as new_value
from mytable t
)
update cte set value = new_value where value is null
如果您特别想要 sequence
具有值 1
的行,请使用条件 window 聚合:
with cte as (
select value,
min(case when sequence = 1 then value end) over(partition by id) as new_value
from mytable t
)
update cte set value = new_value where value is null
最后,如果您想要具有最小值 sequence
的行,而不考虑其实际值:
with cte as (
select value,
first_value(value) over(partition by id order by sequence) as new_value
from mytable t
)
update cte set value = new_value where value is null
DENSE_RANK 窗口函数对于此类序列很方便。如果目标只是 return 的值,则不需要存储它,因为它可以直接在 select.
中获取DECLARE @Test as Table (
Id char(1),
Seq int,
Val varchar(10)
)
INSERT @Test (Id, Seq)
VALUES
('A','1'),
('A','2'),
('A','3'),
('A','4'),
('A','5'),
('B','1'),
('B','2'),
('B','3'),
('B','4'),
('C','4'),
('C','5');
-- Select Only
SELECT Id, Seq,
'Test' + LTRIM(STR(DENSE_RANK() OVER (ORDER BY Id))) as [Val]
FROM @Test
-- Update via derived table
UPDATE t
SET Val = 'Test' + LTRIM(STR(Seq2))
FROM @Test t
INNER JOIN (
SELECT Id, Seq, DENSE_RANK() OVER (ORDER BY Id) as [Seq2]
FROM @Test
) v
ON v.Id = t.Id AND v.Seq = t.Seq