2016-12-01 3 views
2

풍향 예측 데이터가있는 여러 기상 위치가 있습니다. 전날 10:00 전에 가장 최근의 as_of이 필요합니다. 각 시간마다, 각 위치마다이 작업이 필요합니다.다중 열 그룹 식별자가있는 최신 예측 데이터 얻기

위치는 고유 한 latlon 쌍으로 정의됩니다. 관련 샘플 데이터와

전체 테이블 스키마 :

CREATE SCHEMA weather 
CREATE TABLE weather.forecast 
    (
    foretime timestamp without time zone NOT NULL, 
    as_of timestamp without time zone NOT NULL, -- in UTC 
    summary text, 
    precipintensity numeric(8,4), 
    precipprob numeric(2,2), 
    temperature numeric(5,2), 
    apptemp numeric(5,2), 
    dewpoint numeric(5,2), 
    humidity numeric(2,2), 
    windspeed numeric(5,2), 
    windbearing numeric(4,1), 
    visibility numeric(5,2), 
    cloudcover numeric(4,2), 
    pressure numeric(6,2), 
    ozone numeric(5,2), 
    preciptype text, 
    lat numeric(8,6) NOT NULL, 
    lon numeric(9,6) NOT NULL, 
    CONSTRAINT forecast_pkey PRIMARY KEY (foretime, as_of, lat, lon) 
); 

INSERT INTO weather.forecast 
    (windspeed, foretime, as_of, lat, lon) 
VALUES 
    (11.19, '2/1/2016 8:00', '1/30/2016 23:00', 34.556, 28.345), 
    (10.98, '2/1/2016 8:00', '1/31/2016 5:00', 34.556, 28.345), 
    (10.64, '2/1/2016 8:00', '1/31/2016 11:00', 34.556, 28.345), 
    (10.95, '2/1/2016 8:00', '1/31/2016 8:00', 29.114, 16.277), 
    (10.39, '2/1/2016 8:00', '1/31/2016 23:00', 29.114, 16.277), 
    (9.22, '2/1/2016 8:00', '1/31/2016 5:00', 29.114, 16.277), 
    (10,  '2/1/2016 9:00', '1/30/2016 04:00', 34.556, 28.345), 
    (9.88, '2/1/2016 9:00', '1/31/2016 09:00', 34.556, 28.345), 
    (10.79, '2/1/2016 9:00', '1/30/2016 23:00', 34.556, 28.345), 
    (10.8, '2/1/2016 9:00', '1/31/2016 5:00', 29.114, 16.277), 
    (10.35, '2/1/2016 9:00', '1/31/2016 11:00', 29.114, 16.277), 
    (10.07, '2/1/2016 9:00', '1/31/2016 17:00', 29.114, 16.277) 
; 

원하는 결과 형식 :

lat  lon  Foredate foreHE windspeed  as_of 
34.556 28.345 2/1/2016  8  10.98  1/31/2016 5:00 
34.556 28.345 2/1/2016  9  9.88  1/31/2016 9:00 
29.114 16.277 2/1/2016  8  10.95  1/31/2016 8:00 
29.114 16.277 2/1/2016  9  10.80  1/31/2016 5:00 

여기에 올바른 as_of를 얻을 내 코드입니다. 풍속으로 돌아 가려고 할 때 상황이 나빠질 수 있습니다. 난 정말 어쩌면 제외하고는, PostgreSQL을의 오류 메시지 개선 할 수

[42803] ERROR: column "a.windspeed" must appear in the GROUP BY clause or be used in an aggregate function 
    Position: 184 

조금 이론으로 활용하려면 다음 작업을 다시 풍속을 추가 할 때

SELECT   
    date_trunc('day', (a.foretime)) :: DATE AS Foredate, 
     extract(HOUR FROM (a.foretime)) AS foreHE, 
     a.lat, 
     a.lon, 
     max(a.as_of) - interval '5 hours' as latest_as_of 
FROM weather.forecast a 
WHERE date_trunc('day', foretime) :: DATE - as_of >= INTERVAL '14 hours' 
GROUP BY Foredate, foreHE, a.lat, a.lon 

답변

2

귀하의 오류는 이것이다. 기본적으로 GROUP BY을 할 때 나머지 쿼리가 나타내는 테이블 인 더 큰 세트 내의 부분 집합에 대해 사치스러운 행동을하게됩니다. 그러나 SQL은 반복 할 부분 집합을 가질 수 없으므로 데이터베이스에 계산을 알려주고 또 다른 평면 목록을 제공해야합니다.

Postgres에서 제공하는 두 가지 옵션 중에서 대개 하나가 확실한 선택입니다. 예를 들어, a.lon을 제외한 경우 경도로 그룹화하지 않고 위도로만 그룹화하는 것이 분명하며 GROUP BY 절에 추가해야한다는 데 동의하는 것입니다. 그러나이 경우 실제 측정 값으로 그룹화하면 모든 하위 집합에 단 하나의 행이 있으며 이는 유용하지 않습니다. 그래서 처음에는 당신이 집계가 필요한 것처럼 보입니다. 두 번째 문제는이 문제에 대한 집계가 없다는 것입니다. 한숨!

여기 내 생각입니다. 당신은에 의해 볼 필요가 기본 키는 (뒤따라야, as_of, 위도, 경도)와이 쿼리를 노골적으로 그것을 얻을 수 있습니다 :

select 
    foretime, 
    max(as_of) as as_of, 
    lat, lon 
from weather.forecast 
group by foretime, lat, lon; 

지금 당신이, 같은 테이블에 다시 forecast을이 가입 할 수 가장 최근의 예측을 얻을 :

select 
    date_trunc('day', a.foretime)::date as forecast_day, 
    extract(hour from a.foretime) as forecast_hour, 
    a.lat, a.lon, 
    f.windspeed, 
    a.as_of - interval '5 hours' as latest_as_of 
from weather.forecast f 
join (select 
     foretime, 
     max(as_of) as as_of, 
     lat, lon 
     from weather.forecast 
     group by foretime, lat, lon) a using (foretime, as_of, lat, lon); 

를이 다음과 같은 보고서를 생성합니다

forecast_day | forecast_hour | lat | lon | windspeed | latest_as_of 
--------------+---------------+-----------+-----------+-----------+--------------------- 
2016-02-01 |    8 | 34.556000 | 28.345000 |  10.64 | 2016-01-31 06:00:00 
2016-02-01 |    8 | 29.114000 | 16.277000 |  10.39 | 2016-01-31 18:00:00 
2016-02-01 |    9 | 34.556000 | 28.345000 |  9.88 | 2016-01-31 04:00:00 
2016-02-01 |    9 | 29.114000 | 16.277000 |  10.07 | 2016-01-31 12:00:00 
(4 rows) 

이 상관 하위 쿼리와 함께이 작업을 수행하는보다 효율적인 방법은 아마도하지만 난 '을 그것을 성취하는 방법을 모르겠습니다.

편집 : 당신의 출력 형식 일치 :

select 
    a.lat, a.lon, 
    date_trunc('day', a.foretime)::date as forecast_day, 
    extract(hour from a.foretime) as forecast_hour, 
    f.windspeed, 
    a.as_of - interval '5 hours' as latest_as_of 
from weather.forecast f 
    join (select 
      foretime, 
      max(as_of) as as_of, 
      lat, lon 
     from weather.forecast 
     where date_trunc('day', foretime)::date - as_of >= interval '14 hours' 
     group by foretime, lat, lon) a using (foretime, as_of, lat, lon) 
order by lat desc, lon; 

결과 : 당신이 전날 오전 10시 전에 최신 예측의 내 제약을 처리하는 방법을 내가

lat | lon | forecast_day | forecast_hour | windspeed | latest_as_of 
-----------+-----------+--------------+---------------+-----------+--------------------- 
34.556000 | 28.345000 | 2016-02-01 |    8 |  10.98 | 2016-01-31 00:00:00 
34.556000 | 28.345000 | 2016-02-01 |    9 |  9.88 | 2016-01-31 04:00:00 
29.114000 | 16.277000 | 2016-02-01 |    8 |  10.95 | 2016-01-31 03:00:00 
29.114000 | 16.277000 | 2016-02-01 |    9 |  10.80 | 2016-01-31 00:00:00 
(4 rows) 
+0

표시되지 않습니다. latest_as_of 시간 중 일부는 지난 10am입니다. 이것이 나의 쿼리 코드에서 WHERE 절의 목적이다. – otterdog2000

+0

@ otterdog2000 귀하의 요청에 따라 변경했습니다. –

+0

감사합니다.이 코드를 전체 코드와 결합하면 멈출 수 없습니다. 쿼리는 죽일 때까지 그냥 실행됩니다. – otterdog2000