2012-03-20 3 views
0

나는이 내 PostgreSQL을에 다음 표 8.3.14 데이터베이스열 값에 따라 테이블의 타임 슬롯을 찾기

 timestamp   status 
2012-03-12 19:15:01  f 
2012-03-12 19:15:02  f 
2012-03-12 19:15:05  f 
2012-03-12 19:17:01  t 
-- END OF SLOT ONE (change from f to t) 
2012-03-12 19:20:01  f 
2012-03-12 19:25:01  f 
2012-03-12 19:27:01  f 
2012-03-12 20:15:01  t 
-- END OF SLOT TWO (change from f to t) 

없는 나는 다음과 같은 결과를 얻으려면 번호 :

  • 슬롯 1 개 기간 (2012-03-12 19:17:01 - 2012-03-12 19:15:01)
  • 슬롯 2 기간 (2012-03-12 20:15:01 - 2012-03-12 19:20:01))

그래서 상태 값이 f에서 t로 바뀔 때마다 새로운 슬롯이 시작됩니다. 이제 모든 슬롯과 모든 슬롯의 지속 시간을 가져 오려고합니다. 타임 스탬프는 매초 또는 분 단위가 아니며 두 항목 간의 차이가 다소 무작위입니다.

하위 쿼리 및 그룹화에 대해 생각했지만이 문제를 해결하는 방법을 전혀 모릅니다. 그래서 제 질문은 : 가능합니다 :-) 그리고 그것이 있다면, 어떻게 시작해야합니까? 나는 ft 변경 문제로 인해 붙어있어 ...

+0

PostreSQL 버전이란 무엇입니까? –

+0

내 질문 업데이트 ... – strauberry

+1

PG8에서 작동하도록 내 쿼리가 업데이트되었습니다. –

답변

1

만약 당신이 창 기능을 사용하여 원하는 것을 할 수있는 PG의 최신 버전이 있다면 (타임 스탬프 대신에 정수를 가졌지 만, 그렇지 않다. 문제) : 여기

WITH a AS (
SELECT time,rank() OVER (ORDER BY time) 
     FROM (
       SELECT status, time, lag(status,1) OVER (ORDER BY time) AS ls 
      FROM test1 
      ) AS x 
      WHERE status AND NOT ls 
      -- select where the current status is true, the previous is false 
     ), -- a is now the endings of the slots 
b AS (
    SELECT time, rank() OVER (ORDER BY time) 
     FROM (
      SELECT status, time, LAG(status,1)   
       OVER (ORDER BY time) AS ls 
      FROM test1 
      ) AS x 
      WHERE (NOT status AND ls) OR (NOT status AND ls IS NULL) 
     ) -- b is now the beginning of the slots 
    SELECT b.time as time1, a.time as time2 FROM a,b WHERE a.rank=b.rank; 

    time1 | time2 
------+------ 
1 | 4 
5 | 8 
9 | 10 

없이 PG에 대한 쿼리의 버전입니다 : '비 윈도우 기능 버전에서 일하고 있어요 ... 여기

db=> select * from test1; 
time | status 
------+-------- 
1 | f 
2 | f 
3 | f 
4 | t 
5 | f 
6 | f 
7 | f 
8 | t 
9 | f 
10 | t 

(8 rows) 

는 윈도우 함수와 쿼리입니다 창 함수 (실제로 더 짧지 만 명확하지 않음)

SELECT min(time) as time1, time2 FROM 
    (
     SELECT time, status, 
      (
      SELECT time FROM test1 AS y 
       WHERE y.time >= x.time 
       ORDER BY (x.status = y.status)::int, y.time ASC LIMIT 1 
     ) AS time2 
     FROM test1 AS x WHERE NOT status 
    ) AS y GROUP BY y.time2 ORDER BY time2; 
+0

게시물에 감사드립니다. 나는 그것을 완전히 이해하지 못합니다 ... 왜 LAG 함수에서 offset = 1을 사용합니까? 결과 테이블은 무엇을 의미합니까? 5, 6, 7, 8은 4 단계이므로 슬롯 1 - 4와 슬롯 2 - 4를 기대할 것입니다. – strauberry

+1

미안하지만 질문에 대한 오해가 있습니다 ... –

+0

그는 PostgreSQL 8을 사용하고 있습니다. .. 그 버전에는 윈도우 기능이 없습니다 : ( –

관련 문제