복붙노트

[SQL] SQL 쿼리는 이전에 알려진 값의 값으로 행에 NULL 값을 대체

SQL

SQL 쿼리는 이전에 알려진 값의 값으로 행에 NULL 값을 대체

나는 2 열이

date   number       
----   ------
1      3           
2      NULL        
3      5           
4      NULL        
5      NULL        
6      2          
.......

나는 새로운 값으로 NULL 값을 대체 날짜 열에서 이전 날짜에 마지막으로 알려진 값에서 값을 취합니다 예 : 날짜 = 2 번호 = 3, 4 일, 5 번호 = 5, 5의 값은 무작위로 나타나는 NULL.

해결법

  1. ==============================

    1.는 SQL 서버를 사용하는 경우이 작업을해야합니다

    는 SQL 서버를 사용하는 경우이 작업을해야합니다

    DECLARE @Table TABLE(
            ID INT,
            Val INT
    )
    
    INSERT INTO @Table (ID,Val) SELECT 1, 3
    INSERT INTO @Table (ID,Val) SELECT 2, NULL
    INSERT INTO @Table (ID,Val) SELECT 3, 5
    INSERT INTO @Table (ID,Val) SELECT 4, NULL
    INSERT INTO @Table (ID,Val) SELECT 5, NULL
    INSERT INTO @Table (ID,Val) SELECT 6, 2
    
    
    SELECT  *,
            ISNULL(Val, (SELECT TOP 1 Val FROM @Table WHERE ID < t.ID AND Val IS NOT NULL ORDER BY ID DESC))
    FROM    @Table t
    
  2. ==============================

    2.다음은 MySQL의 솔루션입니다 :

    다음은 MySQL의 솔루션입니다 :

    UPDATE mytable
    SET number = (@n := COALESCE(number, @n))
    ORDER BY date;
    

    이 간결하지만, RDBMS의 다른 브랜드에서 필요한 작업을하지 않습니다. 다른 브랜드의 경우, 더 관련 브랜드 별 해결책이 될 수 있습니다. 이 중요한 이유의 우리에게 당신이 사용하고있는 브랜드를 이야기합니다.

    @Pax 댓글을 달았 그것은의 좋은는 벤더 독립적 인,하지만 그 실패는 최대한의 이점에 데이터베이스의 선택한 브랜드를 사용하는 것도 좋다.

    위의 질의에 대한 설명 :

    MySQL의 사용자 변수 @n이다. 그것은 NULL을 시작하고 행을 통해 UPDATE 실행 등의 각 행에 값이 할당됩니다. 수는 NULL이 아닌 경우, @n는 수의 값이 할당됩니다. 수는 NULL의 COALESCE () @n의 이전 값 기본값입니다. 어느 경우에도, 이것은 다수의 컬럼의 새로운 값이되고 업데이트는 다음 행으로 진행한다. @n 변수 정도로 후속 행은 이전 행 (들)에서 온 값을 가져, 행에서 행까지 그 값을 유지한다. 업데이트의 순서는 (이 표준 SQL되지 않습니다) 때문에 UPDATE와 ORDER BY의 MySQL의 특별 사용의 예측이다.

  3. ==============================

    3.가장 좋은 방법은 빌 Karwin 제공하는 것입니다. 최근에 비교적 큰 결과 집합이 문제를 해결했다 (12 열로 1,000 행마다 이러한 유형의 "나에게 마지막 비 - 널이 값이 현재의 행에 대한 널 (null) 인 경우의 값 표시"필요) 및 상부 1 업데이트 방법을 사용하여 (최고 1 또는 하위 쿼리) 이전 알려진 값을 선택 느린 슈퍼 달렸다.

    가장 좋은 방법은 빌 Karwin 제공하는 것입니다. 최근에 비교적 큰 결과 집합이 문제를 해결했다 (12 열로 1,000 행마다 이러한 유형의 "나에게 마지막 비 - 널이 값이 현재의 행에 대한 널 (null) 인 경우의 값 표시"필요) 및 상부 1 업데이트 방법을 사용하여 (최고 1 또는 하위 쿼리) 이전 알려진 값을 선택 느린 슈퍼 달렸다.

    나는 SQL 2005을 사용하고 가변 교체에 대한 구문은 MySQL은 약간 다릅니다 :

    UPDATE mytable 
    SET 
        @n = COALESCE(number, @n),
        number = COALESCE(number, @n)
    ORDER BY date
    

    '수'널 (COALESCE 반환 당신이 그것으로 통과 최초의 null 이외의 인수)가 아닌 경우 첫 번째 세트 문은 '수'의 현재 행의 값으로 변수 @n의 값을 업데이트 두 번째 세트 문은 그 자체로 '수'의 실제 컬럼 값 (없는 경우는 null) 또는 (항상 발생 마지막 비 NULL 값을 포함) 변수 @n를 업데이트합니다.

    이 방법의 장점은 또 다시 임시 테이블을 스캔하고에 소비 추가 자원이 없다는 것입니다 ... @n의에서 행 업데이트는 마지막 null 이외의 값을 추적을 담당한다.

    나는 그의 대답을 투표를하기에 충분한 담당자를 가지고 있지 않지만, 누군가가해야한다. 그것은 가장 우아하고 가장 성능이 좋은입니다.

  4. ==============================

    4.여기에 오라클 솔루션 (10g 이상)입니다. 이는 컬럼의 마지막 비 - 널 값을 대입 널 옵션을 무시하여 분석 LAST_VALUE 함수 ()를 사용한다.

    여기에 오라클 솔루션 (10g 이상)입니다. 이는 컬럼의 마지막 비 - 널 값을 대입 널 옵션을 무시하여 분석 LAST_VALUE 함수 ()를 사용한다.

    SQL> select *
      2  from mytable
      3  order by id
      4  /
    
            ID    SOMECOL
    ---------- ----------
             1          3
             2
             3          5
             4
             5
             6          2
    
    6 rows selected.
    
    SQL> select id
      2         , last_value(somecol ignore nulls) over (order by id) somecol
      3  from mytable
      4  /
    
            ID    SOMECOL
    ---------- ----------
             1          3
             2          3
             3          5
             4          5
             5          5
             6          2
    
    6 rows selected.
    
    SQL>
    
  5. ==============================

    5.다음 스크립트는이 문제를 해결에만 일반 ANSI SQL을 사용합니다. 나는 SQL2008, sqlite3를하고 Oracle11g에이 솔루션을 테스트했다.

    다음 스크립트는이 문제를 해결에만 일반 ANSI SQL을 사용합니다. 나는 SQL2008, sqlite3를하고 Oracle11g에이 솔루션을 테스트했다.

    CREATE TABLE test(mysequence INT, mynumber INT);
    
    INSERT INTO test VALUES(1, 3);
    INSERT INTO test VALUES(2, NULL);
    INSERT INTO test VALUES(3, 5);
    INSERT INTO test VALUES(4, NULL);
    INSERT INTO test VALUES(5, NULL);
    INSERT INTO test VALUES(6, 2);
    
    SELECT t1.mysequence, t1.mynumber AS ORIGINAL
    , (
        SELECT t2.mynumber
        FROM test t2
        WHERE t2.mysequence = (
            SELECT MAX(t3.mysequence)
            FROM test t3
            WHERE t3.mysequence <= t1.mysequence
            AND mynumber IS NOT NULL
           )
    ) AS CALCULATED
    FROM test t1;
    
  6. ==============================

    6.나는 그것이 아주 오래된 포럼입니다 알고 있지만, 단지 다른 사람들이 위의 문제에 조금 복잡한 솔루션을 준 것을 깨달았다 내 문제 : 문제 해결 동안이 가로 질러왔다. 아래에있는 내 솔루션을 참조하십시오 :

    나는 그것이 아주 오래된 포럼입니다 알고 있지만, 단지 다른 사람들이 위의 문제에 조금 복잡한 솔루션을 준 것을 깨달았다 내 문제 : 문제 해결 동안이 가로 질러왔다. 아래에있는 내 솔루션을 참조하십시오 :

    DECLARE @A TABLE(ID INT, Val INT)
    
    INSERT INTO @A(ID,Val) SELECT 1, 3
    INSERT INTO @A(ID,Val) SELECT 2, NULL
    INSERT INTO @A(ID,Val) SELECT 3, 5
    INSERT INTO @A(ID,Val) SELECT 4, NULL
    INSERT INTO @A(ID,Val) SELECT 5, NULL
    INSERT INTO @A(ID,Val) SELECT 6, 2
    
    UPDATE D
        SET D.VAL = E.VAL
        FROM (SELECT A.ID C_ID, MAX(B.ID) P_ID
              FROM  @A AS A
               JOIN @A AS B ON A.ID > B.ID
              WHERE A.Val IS NULL
                AND B.Val IS NOT NULL
              GROUP BY A.ID) AS C
        JOIN @A AS D ON C.C_ID = D.ID
        JOIN @A AS E ON C.P_ID = E.ID
    
    SELECT * FROM @A
    

    이 사람을 도움이 될 수 있습니다 희망 :)

  7. ==============================

    7.당신이 Redshift에 대한 해결책을 찾고 있다면,이 프레임 절과 함께 작동합니다 :

    당신이 Redshift에 대한 해결책을 찾고 있다면,이 프레임 절과 함께 작동합니다 :

    SELECT date, 
           last_value(columnName ignore nulls) 
                       over (order by date
                             rows between unbounded preceding and current row) as columnName 
     from tbl
    
  8. ==============================

    8.우선, 당신은 정말 값을 저장해야합니까? 당신은 방금 일을보기를 사용할 수 있습니다 :

    우선, 당신은 정말 값을 저장해야합니까? 당신은 방금 일을보기를 사용할 수 있습니다 :

    SELECT  t."date",
            x."number" AS "number"
    FROM    @Table t
    JOIN    @Table x
        ON  x."date" = (SELECT  TOP 1 z."date"
                        FROM    @Table z
                        WHERE   z."date" <= t."date"
                            AND z."number" IS NOT NULL
                        ORDER BY z."date" DESC)
    

    당신이 정말로 ID ( "날짜") 열이 수행하고 기본 키 (클러스터) 인 경우,이 쿼리는 꽤 빨리해야합니다. 그러나 쿼리 계획을 확인 :뿐만 아니라 발 열을 포함 커버 인덱스가 더 좋을 수도 있습니다.

    당신이 그들을 피할 수 있습니다 때 절차 좋아하지 않아 또한, 당신은 또한 UPDATE 유사한 쿼리를 사용할 수 있습니다 :

    UPDATE  t
    SET     t."number" = x."number"
    FROM    @Table t
    JOIN    @Table x
        ON  x."date" = (SELECT  TOP 1 z."date"
                        FROM    @Table z
                        WHERE   z."date" < t."date" --//@note: < and not <= here, as = not required
                            AND z."number" IS NOT NULL
                        ORDER BY z."date" DESC)
    WHERE   t."number" IS NULL
    

    참고 : 코드해야는 "SQL 서버"에서 작동합니다.

  9. ==============================

    9.이것은 MS Access의 솔루션입니다.

    이것은 MS Access의 솔루션입니다.

    예제 테이블 필드의 ID와 발과 탭이라고합니다.

    SELECT (SELECT last(val)
              FROM tab AS temp
              WHERE tab.id >= temp.id AND temp.val IS NOT NULL) AS val2, *
      FROM tab;
    
  10. ==============================

    10.

    UPDATE TABLE
       SET number = (SELECT MAX(t.number)
                      FROM TABLE t
                     WHERE t.number IS NOT NULL
                       AND t.date < date)
     WHERE number IS NULL
    
  11. ==============================

    11.경우 하나 개의 신원 (ID)와 하나의 공통 (유형) 열이 :

    경우 하나 개의 신원 (ID)와 하나의 공통 (유형) 열이 :

    UPDATE #Table1 
    SET [Type] = (SELECT TOP 1 [Type]
                  FROM #Table1 t              
                  WHERE t.[Type] IS NOT NULL AND 
                  b.[Id] > t.[Id]
                  ORDER BY t.[Id] DESC)
    FROM #Table1 b
    WHERE b.[Type] IS NULL
    
  12. ==============================

    12.매우 일반적인 의미에서 :

    매우 일반적인 의미에서 :

    UPDATE MyTable
    SET MyNullValue = MyDate
    WHERE MyNullValue IS NULL
    
  13. ==============================

    13.이 시도:

    이 시도:

    update Projects
    set KickOffStatus=2 
    where KickOffStatus is null
    
  14. from https://stackoverflow.com/questions/1345065/sql-query-replace-null-value-in-a-row-with-a-value-from-the-previous-known-value by cc-by-sa and MIT license