web-dev-qa-db-ja.com

特定のパーティションの最後のnull以外の値を選択する-Postgres 10

次の構造のテーブルがあります。

date                city cntry  free  occ
2018-08-13 16:30:00 2    12           5
2018-08-13 16:30:00 2    12     0     
2018-08-13 14:30:00 2    12     1     
2018-08-13 11:00:00 2    12     2     
2018-08-12 13:00:00 2    12     1     
2018-08-12 13:00:00 2    12           4
2018-08-12 08:00:00 2    12           3
2018-08-12 08:00:00 2    12     2     
2018-08-10 15:30:00 2    12           4
  • 日付はtimestamp without timezoneです
  • 残りはnumbers

空きと占有の両方について、特定のcity_id/country_idコンボの以前のnull以外の値を取得したい:

date                city cntry  free  occ
2018-08-13 16:30:00 2    12     0     5
2018-08-13 14:30:00 2    12     1     4
2018-08-13 11:00:00 2    12     2     4
2018-08-12 13:00:00 2    12     1     4
2018-08-12 08:00:00 2    12     2     3
2018-08-10 15:30:00 2    12     1     4
  • パーティションはcity_id, country_id順、date
  • 各パーティションの最初の日付について、NULL値がある場合、それはゼロになります
  • 既存のパーティションの場合、以前の値を使用します
  • City_idとcountry_id AFTERWARDSでフィルタリングできるようにしたい

基本的に、2つのタイムラインをマージしていて、<city_id, country_id>の各パーティションの以前の値(空き/占有)を保持したいと考えています。

無駄にウィンドウ関数で遊んでみました。自由値または占有値のいずれかでデータを取得できますが、両方は取得できません。

どうすればこれを達成できますか?

4
Miguel Ping

MAX関数をcoalesceと組み合わせて使用​​してみてください。

スキーマ(PostgreSQL v9.6)

CREATE TABLE T(
   date date,
   city_id int,
   country_id int,
   free int,
   occupied int
);

insert into T values ('2017-01-01',2,3,null, 2);
insert into T values ('2017-01-02',2,3,4, null);
insert into T values ('2017-01-02',2,3,null, 5);
insert into T values ('2017-01-04',3,4,2, null);

クエリ#1

SELECT
  date,
  city_id,
  country_id,
  coalesce(MAX(free),0) free  ,
  coalesce(MAX(occupied),0) occupied
FROM T
GROUP BY date,city_id,country_id
order by date;

| date                     | city_id | country_id | free | occupied |
| ------------------------ | ------- | ---------- | ---- | -------- |
| 2017-01-01T00:00:00.000Z | 2       | 3          | 0    | 2        |
| 2017-01-02T00:00:00.000Z | 2       | 3          | 4    | 5        |
| 2017-01-04T00:00:00.000Z | 3       | 4          | 2    | 0        |

DB Fiddleで表示

3
D-Shih