1

에서 사용하기 위해 CTE 하위 쿼리 출력 간의 차이를 계산할 수 없습니다. Shell에서 PostgreSQL v9.4.5를 사용하여 을 실행하여 psql에 moments라는 데이터베이스를 만들었습니다.큰 PostgreSQL 쿼리 출력 열

순간 표

id | moment_type | flag |  time   
----+-------------+------+--------------------- 
    1 |   1 | 7 | 2016-10-29 12:00:00 
    2 |   1 | -30 | 2016-10-29 13:00:00 
    3 |   3 | 5 | 2016-10-29 14:00:00 
    4 |   2 | 9 | 2016-10-29 18:00:00 
    5 |   2 | -20 | 2016-10-29 17:00:00 
    6 |   3 | 10 | 2016-10-29 16:00:00 

그때 다음과 같은 출력을 생성하는 SQL 쿼리를 작성하려고 :

CREATE TABLE moments 
(
    id SERIAL4 PRIMARY KEY, 
    moment_type BIGINT NOT NULL, 
    flag BIGINT NOT NULL, 
    time TIMESTAMP NOT NULL, 
    UNIQUE(moment_type, time) 
); 
INSERT INTO moments (moment_type, flag, time) VALUES (1, 7, '2016-10-29 12:00:00'); 
INSERT INTO moments (moment_type, flag, time) VALUES (1, -30, '2016-10-29 13:00:00'); 
INSERT INTO moments (moment_type, flag, time) VALUES (3, 5, '2016-10-29 14:00:00'); 
INSERT INTO moments (moment_type, flag, time) VALUES (2, 9, '2016-10-29 18:00:00'); 
INSERT INTO moments (moment_type, flag, time) VALUES (2, -20, '2016-10-29 17:00:00'); 
INSERT INTO moments (moment_type, flag, time) VALUES (3, 10, '2016-10-29 16:00:00'); 

나는 테이블을 볼 수 select * from moments을 실행 나는 다음 순간 테이블을 생성 , 각각의 중복 된 moment_type 값들의 쌍에 대하여 그것은 가장 최근의 타임 스탬프 값을 갖는 moment_type의 플래그 값과 두 번째의 가장 최근의 타임 스탬프의 플래그 값 사이의 차이를 반환한다 mp 값을 찾고, moment_type에 따라 오름차순으로 결과를 나열합니다.

예상 SQL 쿼리 출력

moment_type | flag | 
------------+------+ 
      1 | -37 | (i.e. -30 - 7) 
      2 | 29 | (i.e. 9 - -20) 
      3 | 5 | (i.e. 10 - 5) 

내가 더 큰 SELECT 쿼리에서의 사용을 임시 테이블에 대한 여러 Common Table Expressions (CET) 하위 쿼리를 작성하는 쿼리를 사용하는 다음과 같다 내놓았다 SQL 쿼리 끝. 나는 또한 (또는 생각 난 그냥 DIFFERENCEDIFFERENCE(most_recent_flag, second_most_recent_flag) AS flag 대신 기능을 사용할 수도) 서브 쿼리 출력의 둘 사이의 차이를 계산하는 SQL function를 사용

CREATE FUNCTION difference(most_recent_flag, second_most_recent_flag) RETURNS numeric AS $$ 
    SELECT $1 - $2; 
$$ LANGUAGE SQL; 

-- get two flags that have the most recent timestamps 
WITH two_most_recent_flags AS (
SELECT moments.flag 
FROM moments 
ORDER BY moments.time DESC 
LIMIT 2 
), 
-- get one flag that has the most recent timestamp 
most_recent_flag AS (
SELECT * 
FROM two_most_recent_flags 
ORDER BY flag DESC 
LIMIT 1 
), 
-- get one flag that has the second most recent timestamp 
second_most_recent_flag AS (
SELECT * 
FROM two_most_recent_flags 
ORDER BY flag ASC 
LIMIT 1 
) 
SELECT DISTINCT ON (moments.moment_type) 
moments.moment_type, 
difference(most_recent_flag, second_most_recent_flag) AS flag 
FROM moments 
ORDER BY moment_type ASC 
LIMIT 2; 

을하지만 PostgreSQL을에 위의 SQL 쿼리를 실행할 때, 그것은 다음과 같은 오류 반환 :

ERROR: column "most_recent_flag" does not exist 
LINE 21: difference(most_recent_flag, second_most_recent_flag) AS fla... 

질문 내가 사용할 수 있습니다 내가 생을 극복하도록하는 방법을 적용 할 수 있습니다 어떤 기술

s 오차를 계산하고 flag 열의 차이를 표시하여 을 얻습니다. 예상 SQL 쿼리 출력?

주 :이

답변

1

:

select moment_type, difference 
from (
    select *, flag- lag(flag) over w difference 
    from moments 
    window w as (partition by moment_type order by time) 
    ) s 
where difference is not null 
order by moment_type 

moment_type | difference 
-------------+------------ 
      1 |  -37 
      2 |   29 
      3 |   5 
(3 rows)  
을 창 기능 row_number()은 첫 번째와 마지막 시간 값을 식별하는 데 사용할 수 있습니다
1

한가지 방법은 조건 집합을 사용하는 테이블 행에 걸쳐 계산을 수행로서 아마도 Window Function 든 사용될 수있다. 사용하여 lag() 윈도우 함수

select m.moment_type, 
     (max(case when seqnum_desc = 1 then flag end) - 
     min(case when seqnum_asc = 1 then flag end) 
     ) 
from (select m.*, 
      row_number() over (partition by m.moment_type order by m.time) as seqnum_asc, 
      row_number() over (partition by m.moment_type order by m.time desc) as seqnum_desc 
     from moments m 
    ) m 
group by m.moment_type;