PostgreSQL 9.5では、reports
という名前のテーブルがあります。
CREATE TABLE public.reports (
id BIGSERIAL PRIMARY KEY,
id_station character(11) NOT NULL,
date date NOT NULL,
element character(4) NOT NULL,
value smallint NOT NULL
);
各ステーション(id_station
列)および毎日(date
列)、I mayには複数の値タイプがあります(要素列):TMIN
、TMAX
、TAVG
(これらの値が存在しない場合があります:特定の日のTMIN
とTMAX
しかありません)。
これは(偽の)サンプルです:
22;"FR069029001";"1925-01-01";"TMAX";130
23;"FR069029001";"1925-01-01";"TMIN";-25
24;"FR069029001";"1925-01-01";"TAVG";0
これらの値を、次の表を使用して、各ステーションおよび毎日の1つの行に統合したいと思います。
CREATE TABLE public.reports_con (
id SERIAL PRIMARY KEY,
id_station character(11) NOT NULL,
date date NOT NULL,
tmin smallint,
tmax smallint,
tavg smallint
);
私はこの結果を達成したいと思います:
454;"FR069029001";"1925-01-01";-25;130;0
このようにPostgreSQLでデータを統合する方法は? CREATE TABLE AS
?
私はそれが次のような再帰クエリでなければならないことを知っています(人間の言語):
For each day:
For each station:
Find values for TMIN, TMAX, TAVG
Insert the results in reports_con in a single row with day and station
私はSQLの学習を開始し、PostgreSQL内でこれを実現したいと思います(Pythonまたはプログラミング言語ではできません)。手伝ってくれませんか?
ターゲットテーブルが明らかに存在するため、_CREATE TABLE AS
_はソリューションとは無関係です。また、再帰的なクエリも必要ありません。
たった3つの列に対して、条件付き集計を使用できます。
_INSERT INTO reports_con (id_station, date, tmin, tmax, tavg)
SELECT id_station, date
, min(value) FILTER (WHERE element = 'TMIN') AS tmin
, min(value) FILTER (WHERE element = 'TMAX') AS tmax
, min(value) FILTER (WHERE element = 'TAVG') AS tavg
FROM reports
GROUP BY id_station, date
ORDER BY id_station, date;
_
集計FILTER
句にはPostgres 9.4が必要です。古いバージョンの詳細と代替:
多数の行の列を増やす(およびパフォーマンスを向上させる必要がある)場合は、実際のcrosstab()
クエリを検討してください。特別な問題は、keyが2つの列で構成されていることですが、onecrosstab()
の場合。これらの関連する回答のように、row_number()
を使用して代理キーを生成します。