窗口函数需严格遵循语法顺序PARTITION BY 必须在 ORDER BY 前LAG/LEAD 的偏移量须为正整数常量并配默认值STRING_AGG 排序须写在函数内取 Top N 优先用 ROW_NUMBER() 并确保排序确定性。窗口函数里 OVER 子句写错顺序结果就全乱了窗口函数不是加个 OVER 就能用对的。常见错误是把排序和分组逻辑混在一起比如写成 OVER (ORDER BY date) 却没加 PARTITION BY结果整张表被当成一个大组排序根本不是你想要的“每组内排序”。真正要分组内转换必须明确两件事按什么字段分组PARTITION BY再在组内按什么排序或计算ORDER BY 或直接聚合。顺序不能颠倒语法上 PARTITION BY 必须在 ORDER BY 前面。PARTITION BY user_id 是分组前提漏掉它所有行就挤在一个逻辑组里如果只写 ORDER BY created_at 不带 PARTITION BYROW_NUMBER() 会从全表第一行开始编号不是每个用户从 1 开始PostgreSQL 和 MySQL 8.0 支持完整语法SQLite 仅支持基础窗口函数不支持 FRAME 子句LAG / LEAD 取不到前一行默认值和偏移量容易设反用 LAG(value, 1) 想取上一行的值但首行总是 NULL——这不是 bug是设计如此。窗口函数不会“跨组”拿数据更不会自动补默认值。关键在第二个参数偏移量和第三个参数默认值。很多人写成 LAG(value, 0) 以为能取当前行其实那是无效偏移也有人漏掉第三个参数导致分组首行无法回退直接丢空。LAG(value, 1, 0) 表示取前 1 行的 value取不到就填 0LEAD(amount, 2, 0.0) 表示取后 2 行的 amount越界就填 0.0偏移量必须是常量正整数不能是列名或表达式否则报错 ERROR: argument of LAG must be a constant用 STRING_AGG 拼接分组字符串排序不生效得靠 ORDER BY 写进函数里STRING_AGG 的排序逻辑不在 OVER 子句里而是在函数参数内部。写成 STRING_AGG(tag, ,) OVER (PARTITION BY id ORDER BY weight) 是错的——ORDER BY 在 OVER 里只影响窗口帧不影响拼接顺序。 RedClaw 百度推出的手机端万能AI Agent助手