복붙노트

[SQL] 어떻게 널 값에 대한 이전 값을 얻을 수 있습니다

SQL

어떻게 널 값에 대한 이전 값을 얻을 수 있습니다

내 테이블의 데이터 아래 있습니다.

   | Id  |  FeeModeId   |Name        |   Amount|
   ---------------------------------------------
   | 1   |  NULL        | NULL       |   20    |
   | 2   |  1           | Quarter-1  |   5000  |
   | 3   |  NULL        | NULL       |   2000  |    
   | 4   |  2           | Quarter-2  |   8000  |
   | 5   |  NULL        | NULL       |   5000  |
   | 6   |  NULL        | NULL       |   2000  |
   | 7   |  3           | Quarter-3  |   6000  |
   | 8   |  NULL        | NULL       |   4000  |

어떻게 출력 이하로 얻을 같은 쿼리를 작성하는 ...

   | Id  |  FeeModeId   |Name        |   Amount|
   ---------------------------------------------
   | 1   |  NULL        | NULL       |   20    |
   | 2   |  1           | Quarter-1  |   5000  |
   | 3   |  1           | Quarter-1  |   2000  |    
   | 4   |  2           | Quarter-2  |   8000  |
   | 5   |  2           | Quarter-2  |   5000  |
   | 6   |  2           | Quarter-2  |   2000  |
   | 7   |  3           | Quarter-3  |   6000  |
   | 8   |  3           | Quarter-3  |   4000  |

해결법

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

    1.시도하십시오 :

    시도하십시오 :

    select 
        a.ID,
        ISNULL(a.FeeModeId, x.FeeModeId) FeeModeId,
        ISNULL(a.Name, x.Name) Name,
        a.Amount
    from tbl a
    outer apply
    (select top 1 FeeModeId, Name 
        from tbl b 
        where b.ID<a.ID and 
            b.Amount is not null and 
            b.FeeModeId is not null and 
            a.FeeModeId is null order by ID desc)x
    

    또는

    select 
        ID,
        ISNULL(FeeModeId, bFeeModeId) FeeModeId,
        ISNULL(Name, bName) Name,
        Amount
    From(
        select 
            a.ID , a.FeeModeId, a.Name, a.Amount, 
            b.ID bID, b.FeeModeId bFeeModeId, b.Name bName,
            MAX(b.FeeModeId) over (partition by a.ID) mx
        from tbl a left join tbl b on b.ID<a.ID
        and b.FeeModeId is not null
    )x 
    where bFeeModeId=mx or mx is null
    
  2. ==============================

    2.당신은 SQL 서버 2012에 있기 때문에 ... 여기에 사용하는 버전입니다. 그것은 빨리 다른 솔루션에 비해 수 있습니다하지만 당신은 당신의 데이터를 테스트해야합니다.

    당신은 SQL 서버 2012에 있기 때문에 ... 여기에 사용하는 버전입니다. 그것은 빨리 다른 솔루션에 비해 수 있습니다하지만 당신은 당신의 데이터를 테스트해야합니다.

    위에 합 () 실행 합계 열에서 값이 1 인 경우를 추가하고 널 값의 현재 값을 유지 ID에 의해 지시 할 것이다. 산출 된 누적 합계 다음 위에 FIRST_VALUE ()에 결과를 분할하기 위해 사용된다 (). 실행 합에 의해 생성 된 각 행 "그룹"에 대한 ID로 정렬 된 첫 번째 값이 원하는 값을가집니다.

    select T.Id,
           first_value(T.FeeModeId) 
              over(partition by T.NF 
                   order by T.Id 
                   rows between unbounded preceding and current row) as FeeModeId,
           first_value(T.Name)      
              over(partition by T.NS 
                   order by T.Id 
                   rows between unbounded preceding and current row) as Name,
           T.Amount
    from (
         select Id,
                FeeModeId,
                Name,
                Amount,
                sum(case when FeeModeId is null then 0 else 1 end) 
                  over(order by Id) as NF,
                sum(case when Name is null then 0 else 1 end) 
                  over(order by Id) as NS
         from YourTable
         ) as T
    

    SQL 바이올린

    이전 SQL 서버 2012 작동합니다 뭔가 :

    select T1.Id,
           T3.FeeModeId,
           T2.Name,
           T1.Amount
    from YourTable as T1
      outer apply (select top(1) Name
                   from YourTable as T2
                   where T1.Id >= T2.Id and
                         T2.Name is not null
                   order by T2.Id desc) as T2
      outer apply (select top(1) FeeModeId
                   from YourTable as T3
                   where T1.Id >= T3.Id and
                         T3.FeeModeId is not null
                   order by T3.Id desc) as T3
    

    SQL 바이올린

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

    3.이 시도 -

    이 시도 -

    SELECT Id,
           CASE
             WHEN Feemodeid IS NOT NULL THEN
              Feemodeid
             ELSE
              (SELECT Feemodeid
                 FROM Table_Name t_2
                WHERE t_2.Id = (SELECT MAX(Id)
                                  FROM Table_Name t_3
                                 WHERE t_3.Id < t_1.Id
                                   AND Feemodeid IS NOT NULL))
            END Feemodeid,
           CASE
             WHEN NAME IS NOT NULL THEN
              NAME
             ELSE
              (SELECT NAME
                 FROM Table_Name t_2
                WHERE t_2.Id = (SELECT MAX(Id)
                                  FROM Table_Name t_3
                                 WHERE t_3.Id < t_1.Id
                                   AND NAME IS NOT NULL))
           END NAME,
           Amount
      FROM Table_Name t_1
    
  4. ==============================

    4.

    SELECT
      T.ID,
      ISNULL(T.FeeModeId, 
        (SELECT TOP 1 FeeModeId 
            FROM TableName AS T1 
            WHERE ID < T.ID AND FeeModeId IS NOT NULL 
            ORDER BY ID DESC)) AS FeeModeId,
      ISNULL(Name,
        (SELECT TOP 1 Name 
        FROM TableName 
        WHERE ID < T.ID AND Name IS NOT NULL 
        ORDER BY ID DESC)) AS Name,
      T.Amount
    FROM
      TableName AS T
    
  5. ==============================

    5.

    id  name
    1   toto
    2   NULL
    3   NULL
    4   titi
    5   NULL
    6   NULL
    7   tutu
    8   NULL
    9   NULL
    
    
    SELECT 
           id_table
           ,name
    FROM 
           (
                 SELECT
                        T_01.id AS 'id_table'
                        ,max(T_02.id) AS 'id_name'
                 FROM
                        names AS T_01
                        cross join  
                        (
                              SELECT
                                     id
                                     ,name
                              FROM
                                     names
                              WHERE
                                     name IS NOT NULL
                        ) AS T_02 
                 WHERE 
                        T_02.id <= T_01.id
                 GROUP BY 
                        T_01.id
           ) AS tt02
           left join names
           ON names.id = tt02.id_name
    
    
    id_table    name
    1           toto
    2           toto
    3           toto
    4           titi
    5           titi
    6           titi
    7           tutu
    8           tutu
    9           tutu
    
  6. from https://stackoverflow.com/questions/16669620/how-to-get-previous-value-for-null-values by cc-by-sa and MIT license