2014-11-12 2 views
0

쿼리는 null 값을 확인하고 가장 최근의 null이 아닌 값으로 바꿉니다.

예를 들어 아래 제공된 소스 데이터를 고려하십시오.null을 확인하고 null이 아닌 최근 값을 바꿉니다.

쿼리는 null 값을 검사해야하며 두 번째 행에서 null 값을 null이 아닌 최근 데이터로 바꿔야하고 데이터는 "colmin"으로 바뀌어야합니다.

다시 쿼리는 null 값을 확인해야하며 이제는 세 번째 행에서 찾은 다음 최근 null이 아닌 데이터로 업데이트되고 데이터는 다시 "colmin"입니다.

미리 감사드립니다.

입력

source data  
Colmin  
NULL 
NULL 
NULL 
NULL 
columnxy 
column99 
NULL 
NULL 
money 
NULL 
NULL 
NULL 
start end 
NULL 

때문에 출력이

출력

Ouput data 
Colmin  
Colmin  
Colmin  
Colmin  
Colmin  
Colmin  
columnxy 
column99 
column99 
column99 
money 
money 
money 
money 
start end 
start end 
+1

신난다. 논리 Benjamin, John Bevan에 감사드립니다. –

답변

0

이 시도 :

declare @input table (id bigint not null identity(1,1), OutputData nvarchar(16) null) 
insert @input select 'Colmin'  
insert @input select NULL 
insert @input select NULL 
insert @input select NULL 
insert @input select NULL 
insert @input select 'columnxy' 
insert @input select 'column99' 
insert @input select NULL 
insert @input select NULL 
insert @input select 'money' 
insert @input select NULL 
insert @input select NULL 
insert @input select NULL 
insert @input select 'start end' 
insert @input select NULL 

--where a's value is null, replace with a non-null from b 
select coalesce(a.OutputData, b.OutputData) 
--return all rows from input as a 
from @input a 
--return all non-null values as b 
left outer join 
(
    select id, OutputData 
    from @input 
    where OutputData is not null 
) b 
--the non-null value should come before the null value (< or <= works equally here) 
on b.id <= a.id 
--and there shouldn't be a non-null value between b and a's records (i.e. b is the most recent before a) 
and not exists (
    select top 1 1 
    from @input c 
    where c.id between b.id and a.id 
    and c.id <> b.id 
    and c.OutputData is not null 
) 
--display the output in the required order 
order by a.id 
+0

ps. 귀하의 질문은 데이터에 어떤 종류의 질서를 암시합니다. 이 명령을 내리는 ID 필드라고 가정했습니다. 그러나 위의 코드는 프로그래밍 방식으로 정렬 할 수있는 모든 열에 적용됩니다. – JohnLBevan

1

는 "가장 최근"이란 무엇입니까 .. 같이해야합니까? 정렬 할 필드가 있으면 좋겠다. 행 번호는 항상 올바른 순서로되어서는 안됩니다 (MUST NOT). 비록 내가 행의 순서를 결정하는 데 사용됩니다 orderField을 사용하고 싶지만.

UPDATE myTable 
SET a = (
    SELECT a 
    FROM myTable 
    WHERE a IS NOT NULL 
    AND orderField > (
     SELECT orderField 
     FROM myTable 
     WHERE a IS NULL 
     ORDER BY orderField 
     LIMIT 1 
    ) 
    ORDER BY orderField 
    LIMIT 1 
) 
WHERE a IS NULL 
ORDER BY orderField 

이와 같이해야합니다. 그것은 테스트되지 않았습니다.

그것은 무엇을 :

  1. 찾기 "orderField"를 첫 번째 행에 대한 1.에서 값 업데이트 1.
  2. 에서 orderField 후 = 널
  3. 첫째 찾기 값 (= 널!)와 함께 그것은 또한 더 쉽게 작동합니다 2.

에서 값 :

UPDATE myTable t1 
SET t1.a = (
    SELECT t2.a 
    FROM myTable t2 
    WHERE t2.a IS NOT NULL 
    AND t2.orderField > t1.orderField 
    ORDER BY t2.orderField 
    LIMIT 1 
) 
WHERE t1.a IS NULL 
0

테이블이 단일 열인 경우 루프에서 여러 쿼리를 실행하거나 커서를 사용하여 한 번에 한 행씩 테이블을 반복 할 수 있습니다. (효율적이지 않습니다.)

ID 열의 종류가있는 경우 상관 하위 쿼리를 사용하여 첫 번째 비 null 값을 찾을 수 있습니다. 뭔가 같은 ...

Update A 
Set TextCol = (SELECT Top 1 TextCol From MyTable B Where B.TextCol IS NOT NULL AND B.IDCol < A.IDCol ORDER BY IDCol DESC) 
FROM MyTable A 
WHERE TextCol IS NULL 
+0

작동하지 않습니다. 잘못된 논리입니다! –

+0

로직이 잘 작동합니다. 구문에는 작은 문제가있었습니다 ... 업데이트 문에는 SQL Server에서 작동하는 별칭이 필요했습니다. 여기에 SqlFiddle이 있습니다. http://sqlfiddle.com/#!3/c26bd5/5 – DeadZone

관련 문제