【PostgreSQL】SQLで前の行、または次の行の値を取得したい

SQLで前の行、または次の行の値を取得したい

今回使用した環境

インターネット接続可能のオンラインの環境

64 ビット オペレーティング システム

Windows 10 22H2

PostgreSQL 14.4

実現したいこと

前の行、または次の行の値を取得して何かいいことがあるのか?

という話になると思いますが、以下のようなEXCELを作ることを想定します。重複している名称を消したいという要望があるとしてそれに応えます。

もちろんEXCEL上で操作しても消すことはできるのですが、これをSQLで消します。

上記を実現させるためにPostgreSQLウィンドウ関数の「lag」( 前の行の値を参照する ) を使います。

今回は使いませんが、「lag」と全く同じ使い方で「lead」( 次の行の値を参照する ) というウィンドウ関数もあるのでセットで覚えておくとよいでしょう。

テーブル定義とデータ

テーブルは以下を使います。

create table tbl_profit (
    name character varying(20)          -- 担当者
  , area character varying(20)          -- 地区
  , date timestamp(6) without time zone -- 日付
  , profit numeric(10)                  -- 売上
);

データは以下を使います。

insert into tbl_profit values ('伊集院','秋田県','2024/07/01','7000');
insert into tbl_profit values ('伊集院','秋田県','2024/07/06','5000');
insert into tbl_profit values ('伊集院','岩手県','2024/07/15','9000');
insert into tbl_profit values ('伊集院','岩手県','2024/06/10','11000');
insert into tbl_profit values ('伊集院','岩手県','2024/06/23','4000');
insert into tbl_profit values ('北屋敷','青森県','2024/07/28','6000');
insert into tbl_profit values ('北屋敷','青森県','2024/07/03','3000');
insert into tbl_profit values ('北屋敷','青森県','2024/06/22','12000');

抽出のSQL

以下が抽出のSQLです。

「lag」関数は前の行が存在しない場合、nullが返ってくるのでnullの場合はcoalesceでブランクに置き換えて比較しています。

  select case when name <> coalesce(
                             lag(name, 1) over (order by name, area)
                           , '') 
         then name 
         else '' end as 担当者
        ,case when area <> coalesce(
                             lag(area, 1) over (order by name, area)
                           , '')
         then area
         else '' end as 地区
        ,date        as 日付
        ,profit      as 売上
    from tbl_profit
order by name

動作確認

想定していた結果を取得することができました。これをEXCELに貼り付ければOKです。

以上となります。

ここまでお読みいただきありがとうございました。

PostgreSQL

Posted by だゆう