You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL关联Notification与Photo表匹配通知后首条照片方案问询

原写法错误原因

你写的子查询是全局关联通知和照片后仅返回1条匹配结果,无法为每条通知单独匹配对应同设备下时间晚于通知的第一条照片。


正确实现方案1:LATERAL JOIN(PostgreSQL特有,性能最优)

LATERAL JOIN允许子查询引用外层查询的字段,为每条通知单独执行子查询匹配符合要求的第一条照片:

SELECT
  n.notification_timestamp,
  n.data1,
  p.photo_timestamp,
  p.data2 AS data,
  n.deviceid
FROM public.notification n
LEFT JOIN LATERAL (
  SELECT photo_timestamp, data2
  FROM public.photo
  WHERE deviceid = n.deviceid
    AND photo_timestamp >= n.notification_timestamp
  ORDER BY photo_timestamp ASC
  LIMIT 1
) p ON true
-- 保留原有过滤条件
WHERE n.notification_timestamp > '2021-10-28 01:37:20.305+00'::TIMESTAMPTZ - INTERVAL '7 days'
ORDER BY n.deviceid ASC, n.notification_timestamp DESC
LIMIT 100;

该方案适合数据量较大的场景,只要在photo(deviceid, photo_timestamp)上建立联合索引,查询效率会非常高。


正确实现方案2:窗口函数(兼容标准SQL)

先关联所有符合设备和时间条件的通知和照片,再用窗口函数筛选每个通知对应的最早照片:

WITH matched_photos AS (
  SELECT
    n.notification_timestamp,
    n.data1,
    p.photo_timestamp,
    p.data2 AS data,
    n.deviceid,
    -- 按通知ID分组,照片时间升序排序,最早的照片编号为1
    ROW_NUMBER() OVER (PARTITION BY n.id1 ORDER BY p.photo_timestamp ASC) AS rn
  FROM public.notification n
  LEFT JOIN public.photo p
    ON p.deviceid = n.deviceid
    AND p.photo_timestamp >= n.notification_timestamp
  WHERE n.notification_timestamp > '2021-10-28 01:37:20.305+00'::TIMESTAMPTZ - INTERVAL '7 days'
)
SELECT notification_timestamp, data1, photo_timestamp, data, deviceid
FROM matched_photos
WHERE rn = 1
ORDER BY deviceid ASC, notification_timestamp DESC
LIMIT 100;

内容的提问来源于stack exchange,提问作者Purushoth.Kesav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 03:06:04