postgresql:加入第n行

postgresql:加入第n行,sql,postgresql,greatest-n-per-group,Sql,Postgresql,Greatest N Per Group,我有一个用户表和一个订单表 表users有一个主键user\u id和一些其他字段。表orders有一个外键用户id、一个名称订单名称和一个日期订单日期 对于旧版导出,我需要构建一个以表单形式返回数据的查询 user_id | order_name1 | order_name2 | order_name3 我的想法是查询客户并与select to orders进行三次连接 SELECT users.*, order1.order_name AS order_name1, order2.o

我有一个用户表和一个订单表

表users有一个主键
user\u id
和一些其他字段。表orders有一个外键
用户id
、一个名称
订单名称
和一个日期
订单日期

对于旧版导出,我需要构建一个以表单形式返回数据的查询
user_id | order_name1 | order_name2 | order_name3

我的想法是查询客户并与select to orders进行三次连接

SELECT 
 users.*,
 order1.order_name AS order_name1,
 order2.order_name AS order_name2,
 order3.order_name AS order_name3
 FROM users AS users
JOIN (
 SELECT
  user_id,
  order_name,
  order_date
 FROM orders ORDER BY order_date DESC OFFSET 0 LIMIT 1)
AS order1 ON order1.user_id=users.user_id
JOIN (
 SELECT
  user_id,
  order_name,
  order_date
 FROM orders ORDER BY order_date DESC OFFSET 1 LIMIT 1)
AS order2 ON order2.user_id=users.user_id
JOIN (
 SELECT
  user_id,
  order_name,
  order_date
 FROM orders ORDER BY order_date DESC OFFSET 2 LIMIT 1)
AS order3 ON order3.user_id=users.user_id
但是,这不起作用,因为它只从订单中返回一行,而不是专门针对每个用户

如何编写这样的查询?

您可以使用a为每个用户的行编号:

SELECT users.*,
       o.order_name,
       o.rn as order_number
FROM users AS users
JOIN ( SELECT user_id,
              order_name,
              order_date, 
              row_number() over (Partition by user_id) order by order_date desc as rn
       FROM orders
) AS o ON o.user_id = users.user_id and o.rn <= 3;
如果
users.user\u id
是该表的主键,则可以从
users
表中添加其他列,而无需将它们添加到
分组依据中

从Postgres 9.4开始

max(case when o.rn = 1 then o.order_name end) as order_name1
也可以写成:

max(o.order_name) filter (where o.rn = 1) as order_name1
您可以使用编号为每个用户的行编号:

SELECT users.*,
       o.order_name,
       o.rn as order_number
FROM users AS users
JOIN ( SELECT user_id,
              order_name,
              order_date, 
              row_number() over (Partition by user_id) order by order_date desc as rn
       FROM orders
) AS o ON o.user_id = users.user_id and o.rn <= 3;
如果
users.user\u id
是该表的主键,则可以从
users
表中添加其他列,而无需将它们添加到
分组依据中

从Postgres 9.4开始

max(case when o.rn = 1 then o.order_name end) as order_name1
也可以写成:

max(o.order_name) filter (where o.rn = 1) as order_name1

你救了我的命!感谢您指出窗口功能!你救了我的命!感谢您指出窗口功能!