こぼれネット

修正版SQL(from=乗車停留所, to=降車停留所, trips=件数)

メモ残しておかんと、青冷めるので残しておく。

WITH with_stop AS (
  SELECT
    l.psg_id,
    l.ride_time,
    l.on_off,
    -- stop_tsubame.name 先頭の「番号+(. or .)」を落として、
    -- stop_num から "N. " を付け直す(=> "1. 平高山" 形式)
    (s.stop_num::text || '. ' ||
      regexp_replace(s.name, '^[0-9]+[.\.]\s*', '')
    ) AS stop_name
  FROM log_pass_tsubame l
  JOIN LATERAL (
    SELECT stop_num, name, geom
    FROM stop_tsubame
    ORDER BY l.geom <-> geom
    LIMIT 1
  ) s ON true
),
seq AS (
  SELECT
    psg_id,
    ride_time,
    on_off,
    stop_name,
    -- 乗車(1)が出たら trip_no を +1(psg_id 内で乗車ごとにトリップ区切り)
    SUM(CASE WHEN on_off = 1 THEN 1 ELSE 0 END)
      OVER (PARTITION BY psg_id ORDER BY ride_time) AS trip_no
  FROM with_stop
),
od AS (
  SELECT
    psg_id,
    trip_no,
    -- 同一 trip_no の最初の乗車停留所
    (array_agg(stop_name ORDER BY ride_time)
      FILTER (WHERE on_off = 1))[1] AS "from",
    -- 同一 trip_no の最後の降車停留所(降車が複数あっても最後を採用)
    (
      array_agg(stop_name ORDER BY ride_time)
        FILTER (WHERE on_off = 0)
    )[
      array_length(
        array_agg(stop_name ORDER BY ride_time)
          FILTER (WHERE on_off = 0)
      , 1)
    ] AS "to"
  FROM seq
  WHERE trip_no > 0
  GROUP BY psg_id, trip_no
)
SELECT
  "from",
  "to",
  COUNT(*) AS trips
FROM od
WHERE "from" IS NOT NULL
  AND "to" IS NOT NULL
  AND "from" <> "to"
GROUP BY "from", "to"
ORDER BY "from", "to";

これで直る点


もし「期間指定」も当時入れていたなら、with_stop に条件を足します(例)。

WHERE l.ride_time >= '2025-01-01'::timestamp
  AND l.ride_time <  '2025-02-01'::timestamp

モバイルバージョンを終了