2017-12-14 9 views
3

열에 연속적인 0을 찾거나 0이 아닌 값을 찾으면 어떻게 멈 춥니 다. 그런 다음 모든 0을 0이 아닌 숫자로 바꿔야합니다. ABC는, 그 이외의 제로 값으로 위의 모든 값을 대체 - 우리가 예를 들어, 0이 아닌 값을 얻을 후 열에서 연속 제로를 찾는 방법은 무엇입니까?

  1. 그룹화

    컬럼 1
  2. 에 의해 수행됩니다.
  3. 그룹의 정렬은 날짜의 내림차순으로 수행됩니다.

제로 값을 0이 아닌 숫자로 업데이트하는 방법을 알려주십시오.

+5

더 많은 0과 0이 아닌 더 큰 데이터 세트로 질문을 업데이트 할 수 있습니까? 또한, 순서를 정의하는 데 사용할 수있는 열을 알려주지 않으면 잘 정의 된 0의 시퀀스가없는 것입니다. –

+0

@TimBiegeleisen 지금 확인하십시오. – Ironman10

+0

두 번째 열의 세 번째 행이 두 번째 데이터 집합에서 ABC에 대해 0 인 경우 요구 사항에 따라 3이어야합니다. – Rams

답변

2

enter image description here이 출력을 인이

DECLARE @T TABLE 
(
    Col1 VARCHAR(5), 
    Col2 INT, 
    Col3 DATE 
) 

INSERT INTO @T 
values('ABC',0,'01-01-2017'),('ABC',0,'01-01-2017'),('ABC',0,'01-01-2014'),('ABC',3,'01-01-2013'), 
('DEF',0,'01-01-2017'),('DEF',2,'01-01-2017'),('DEF',0,'01-01-2014') 

;WITH CTE 
AS 
(
SELECT 
    SeqNo = ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2,Col3), 
    RN = ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2 DESC), 
    * 
    FROM @T 
) 
SELECT 
    T1.Col1, 
    NewCol2 = ISNULL(T2.Col2,T1.Col2), 
    OldCol2 = T1.Col2, 
    T1.Col3 
    FROM CTE T1 
     LEFT JOIN CTE T2 
      ON T1.Col1 = t2.Col1 
       AND T1.Col2 = 0 
       AND T2.RN =1 

사용해

enter image description here

프로그램 로직 : 그것은 Col2의 및 COL3에 기초하여 각각 COL1위한 시퀀스를 생성

  • . 0뿐만 Col2의 함께 모든 기록 용
  • , 그것은 일치하는 경우
  • (값 <> 0으로 기록 될 것이다 1 레벨) COL1 랭크 = 1과 같은 값을 갖는 레코드에 대해 동일 테이블 룩업을 수행 위 결과에 따라 일치하는 값이 표시됩니다. 그렇지 않으면 값이 열과 같이 표시됩니다.
+0

좋은 것. 하지만 마지막 행은 2가 업데이트되기 전과 업데이트되지 않아야합니다. – Ironman10

+0

마지막 정의 방법은 무엇입니까? 날짜에 따라? –

+0

예. 날짜를 기준으로합니다. – Ironman10

-1

데이터를 주문하려면 자동 증가 'idx'또는 시간과 같은 열을 추가해야합니다.

다음

update table set Column2=3 where idx > (select idx from table where Column2!=0 limit 0,1) 
+1

이와 같이 데이터를 볼 필요가 있기 때문에 새 열을 추가하는 것은 좋지 않습니다. –

2

당신은이 솔루션을 시도 할 수 있습니다,하지만 당신은 또한 id 열 (내가 추천 자동 증가)가 필요합니다 :

declare @tbl as table (
    id int 
    ,column1 varchar(5) 
    ,column2 int 
) 

insert into @tbl values (1, 'ABC', 0) 
insert into @tbl values (2, 'DEF', 0) 
insert into @tbl values (3, 'GHI', 0) 
insert into @tbl values (4, 'JKL', 3) 
insert into @tbl values (5, 'GHI', 0) 
insert into @tbl values (6, 'JKL', 0) 
insert into @tbl values (7, 'JKL', 4) 

SELECT 
    id 
    ,column1 
    ,CASE WHEN 
     column2 = 0 THEN 
      (SELECT TOP 1 column2 
      FROM @tbl <-- here you query the table again 
      WHERE id > T.id <-- based on this condition you are looking onto the next row (as explained below) 
       AND column2 <> 0 
      ORDER BY id) 
     ELSE column2 
    END AS column2 
FROM @tbl T <-- Here is T; is the alias of the table 

UPDATE를


서브 키가 column2 = 0 인 경우 ry는 테이블을 조사하여 찾은 첫 번째 0이 아닌 값을 취합니다.

WHERE id > T.id 같은 테이블에서 하위 쿼리가 필요하므로 id 열에 대해 알려 줬습니다. 쿼리가 다음 행을 찾았습니다. 0이 아닌 값이 있으면 반환하고, 그렇지 않으면 결과를 반환합니다. 다음 행을 보면 ...

예를 들어, id = 1 테이블에서 하위 쿼리를 검색하면 id > 1의 첫 번째 0이 아닌 값을 검색 할 수 있습니다. 이 경우 하위 쿼리는 id = 4으로 레코드를 찾고 값 3을 반환하고 나머지는 CASE 문이 반환합니다.

+0

다음 코드를 설명해주십시오 : where id> T.id? T.id 무엇입니까? – Ironman10

+0

@SaranshArora 답변을 업데이트했습니다. – Valerica

0

불행히도 테이블의 다음 또는 이전 행을 찾으려면 "ORDER BY"필드를 사용해야합니다. 행이 삽입 된 것으로 주문 된 것을 볼 수 있지만 이것이 보장되는 것은 아닙니다. . 열 1의 모든 유형이 솔루션은 잘 작동 후 아래 하나의 영이 아닌 값을 갖는 경우

; with cte as (
select 
    z.*, s.id sid, s.Column2 sColumn2, 
    row_number() over (partition by z.id order by s.id) as rn 
from zeros as z, zeros as s 
where 
    z.id < s.id and 
    z.Column2 = 0 and 
    s.Column2 > 0 
) 
update z 
set 
    Column2 = upd.sColumn2 
from zeros as z 
inner join (
select 
    id, sColumn2 
from cte 
where rn = 1 
) upd 
on z.id = upd.id 
0

다음 또는 이전 인 당신의 행을 정렬 및 참조에 대한 정체성과 같은 열, 또는 날짜 열을하는 것이 안전합니다.

SELECT t1.column1,coalesce(t2.column2,t1.column2) as column2,t1.column3 FROM TABLE t1 
     LEFT JOIN (SELECT column1,column2,column3 FROM TABLE WHERE column2<>0) AS t2 
     ON t1.column1=t2.column1 and t1.column3>=t2.column3 
     ORDER BY t1.column1,t1.column3 DESC