복붙노트

[SQL] 열 값이 변경 선택 행

SQL

열 값이 변경 선택 행

하자 나는 다음과 같은 테이블이 있다고 가정 :

Value    Time
0        15/06/2012 8:03:43 PM
1        15/06/2012 8:03:43 PM     *
1        15/06/2012 8:03:48 PM 
1        15/06/2012 8:03:53 PM
1        15/06/2012 8:03:58 PM     
2        15/06/2012 8:04:03 PM     *
2        15/06/2012 8:04:08 PM
3        15/06/2012 8:04:13 PM     *
3        15/06/2012 8:04:18 PM
3        15/06/2012 8:04:23 PM
2        15/06/2012 8:04:28 PM     *
2        15/06/2012 8:04:33 PM     

어떻게, 즉, 값이 변경된 경우 별표 행을 선택합니까? 기본적으로 나는 그 시간 간격에 따라 다른 쿼리를 수행 할 수 있도록 값이 변경 시간을 찾기 위해 노력하고있어. 이 솔루션은 사전에 값 또는 시간을 알고에 의존해서는 안된다.

이 매우 어렵지 않을 것을 나에게 보인다 (그러나 그것은 분명히 나를 위해 열심히이다!).

새 창 / 분석 기능이 도움이되는 경우 I 2012에 액세스 할 수 있지만 저는 현재 SQL 서버 2008을 사용하고 있습니다.

내가 여기에 솔루션을 적응 노력 http://blog.sqlauthority.com/2011/11/24/sql-server-solution-to-puzzle-simulate-lead-and-lag-without-using-sql-server-2012- 분석 기능 /하지만 내 쿼리가 한 시간 후에 완료되지 않았습니다! 나는이 관리하기 어려운 뭔가를 행 크기를 폭발 조인 생각 (또는 나는 그것을 망쳐).

나는 C # 코드 및 다수의 DB 호출이 문제를 해결할 수 있지만, 그것은 훨씬 더 좋은 것 테이블 반환 함수 또는 SP에서 할 수있는 일처럼 보인다.

즉 쉽게 경우에도, 단지 값이 증가함에 따라 작동하는 솔루션은 OK입니다.

해결법

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

    1.나는이 필요하시면 생각 :

    나는이 필요하시면 생각 :

    ;WITH x AS
    (
      SELECT value, time, rn = ROW_NUMBER() OVER 
      (PARTITION BY Value ORDER BY Time)
      FROM dbo.table
    )
    SELECT * FROM x WHERE rn = 1;
    

    결과 집합이 큰 인덱스를 지원하는 좋은이없는 경우이 느려질 수 있습니다 ...

    편집하다

    아, 잠깐만, 값이 아니라 위, 아래 가서 ... 이런 경우이 훨씬 느린 접근 방법을 시도 할 수 있습니다 :

    DECLARE @x TABLE(value INT, [time] DATETIME)
    
    INSERT @x VALUES
    (0,'20120615 8:03:43 PM'),--
    (1,'20120615 8:03:43 PM'),--*
    (1,'20120615 8:03:48 PM'),--
    (1,'20120615 8:03:53 PM'),--
    (1,'20120615 8:03:58 PM'),--
    (2,'20120615 8:04:03 PM'),--*
    (2,'20120615 8:04:08 PM'),--
    (3,'20120615 8:04:13 PM'),--*
    (3,'20120615 8:04:18 PM'),--
    (3,'20120615 8:04:23 PM'),--
    (2,'20120615 8:04:28 PM'),--*
    (2,'20120615 8:04:33 PM');
    
    ;WITH x AS
    (
      SELECT *, rn = ROW_NUMBER() OVER (ORDER BY time)
      FROM @x
    )
    SELECT x.value, x.[time]
    FROM x LEFT OUTER JOIN x AS y
    ON x.rn = y.rn + 1
    AND x.value <> y.value
    WHERE y.value IS NOT NULL;
    

    결과 :

    value  time
    -----  -----------------------
    1      2012-06-15 20:03:43.000
    2      2012-06-15 20:04:03.000
    3      2012-06-15 20:04:13.000
    2      2012-06-15 20:04:28.000
    
  2. ==============================

    2.

    DECLARE @x TABLE(value INT, [time] DATETIME)
    
    INSERT @x VALUES
    (0,'20120615 8:03:43 PM'),--
    (1,'20120615 8:03:43 PM'),--*
    (1,'20120615 8:03:48 PM'),--
    (1,'20120615 8:03:53 PM'),--
    (1,'20120615 8:03:58 PM'),--
    (2,'20120615 8:04:03 PM'),--*
    (2,'20120615 8:04:08 PM'),--
    (3,'20120615 8:04:13 PM'),--*
    (3,'20120615 8:04:18 PM'),--
    (3,'20120615 8:04:23 PM'),--
    (2,'20120615 8:04:28 PM'),--*
    (2,'20120615 8:04:33 PM');
    
    
    ; with temp as
    (
    SELECT 
        value, [time],  lag(value,1,-1) over (order by [time] ) as lastValue
    FROM    @x
    ) 
    SELECT 
        [value],[time] 
    FROM 
        temp 
    WHERE value <> lastValue
    

    결과 :

    value   time
    ---------------------------
    0   2012-06-15 20:03:43.000
    1   2012-06-15 20:03:43.000
    2   2012-06-15 20:04:03.000
    3   2012-06-15 20:04:13.000
    2   2012-06-15 20:04:28.000
    
  3. ==============================

    3.우리는 또한이 사용하는 서브 쿼리를 수행 할 수 있습니다

    우리는 또한이 사용하는 서브 쿼리를 수행 할 수 있습니다

    SELECT sub1.value, sub1.time FROM 
      (SELECT *,rn,id FROM 
         (SELECT *,row_number() over (partition by value order by time) AS rn, row_number() over (order by time) AS id FROM x ) order by time) sub1
      LEFT OUTER JOIN 
      (SELECT *,rn,id FROM 
         (SELECT *,row_number() over (partition by value order by time) AS rn, row_number() over (order by time) AS id FROM x ) order by time) sub2
      ON sub1.id = sub2.id + 1 
      WHERE sub1.rn - sub2.rn <> 1 OR sub2.rn IS NULL;
    

    그 다음, RN의 차이는 그 차이를 다음 행의 RN 값 1 그래서, 촬상 한 모든 행을 증가시킬 것이다 1 개 달리 RN 값과 같지 않은 것 변경한다면, I는 2 행의 값을 비교 한 1 아니며 sub2.rn은이 식 (2)로부터 발생하기 때문에 NULL 가입이 첫 번째 행에 사용된다.

  4. from https://stackoverflow.com/questions/11127461/select-rows-where-column-value-has-changed by cc-by-sa and MIT license