2013-10-14 2 views
1

이것은 SQL 101 일 수 있지만 그다지 나에게 충격을줍니다.NULL 값을 가진 모든 레코드를 다음 기존 값으로 업데이트하는 방법

나는 다음과 같은 데이터를 가지고 :

ID  ZipCode  Value 
1  12345  1 
2  12346  Null 
3  12347  Null 
4  12348  2 
5  12349  3 
6  12350  Null 
7  12351  Null 
8  12352  4

나는 가능한 다음 값으로 업데이트되는 널 (null) '값을'이 레코드를 업데이트하는 방법이 필요합니다.

예 :

ID  ZipCode  Value 
1  12345  1 
2  12346  2 
3  12347  2 
4  12348  2 
5  12349  3 
6  12350  4 
7  12351  4 
8  12352  4

내가이 커서 쉽게 충분히 수행 할 수 있다고 생각하지만, 더 나은 방법이 있어야한다.

+1

코드를 요청하는 질문은 해결 된 문제에 대해 최소한의 이해를 보여 주어야합니다. 시도한 해결책을 포함시키고 왜 실패했는지 설명하십시오. – Kermit

+0

Google에서 "SQL에서 누락 된 날짜 범위 찾기"와 관련된 몇 가지 사항을 발견했습니다 .... –

+0

또한 관련 태그도 포함하여 SQL 언어를 지정하십시오. – geomagas

답변

2

커서를 사용할 필요가 없습니다. 단일 명령문에서 테이블을 갱신하는 것은 까다로울 수 있습니다. ID 사이에 간격이있는 경우

WITH B AS 
(
SELECT ID, (SELECT MIN(Value) 
      FROM MyTable 
      WHERE ID > A.ID AND MyTable.Value IS NOT NULL) ValueToAssign 
FROM MyTable A 
WHERE Value IS NULL 
) 


UPDATE MyTable 
SET Value = B.ValueToAssign 
FROM MyTable JOIN B ON MyTable.ID = B.ID 
+0

null 레코드를 업데이트하지만이 레코드를 모두 사용할 수있는 다음 값이 아닌 가장 높은 'Value'(4)로 업데이트합니다. MS SQL Server 2008을 사용하고 있습니다. R2가 아닙니다. –

+0

@GregBaker - 내 편집을 참조하십시오. –

+0

완벽한! 정확히 내가 무엇을 찾고 있었는지. 나는 당신의 코드를 진지하게 분석 할 것이다. –

0

의미가 있습니다 :

그래서 안전을 위해 내가 먼저 NULL 값을 지정하는 값으로 설정 한 결과를 얻을 것입니다.

여기에 데모가 SqlFiddle입니다.

;with cte 
as 
(
select ID, ZipCode, Value, ROW_NUMBER() OVER(ORDER BY ID) rn 
from tb o 
) 
, ct 
as 
(
select top 1 * 
from cte 
order by rn desc 

union all 

select t.ID, t.ZipCode, 
case when t.Value is null then o.Value else t.Value end 'Value', t.rn 
from cte t inner join ct o on t.rn = o.rn - 1 
) 

update tb 
set Value = ct.Value 
from tb inner join ct on tb.ID = ct.ID 
where tb.Value is null 
관련 문제