[英]Combine selected data into same row based on column id (order)
I have a combination of tables that are used to described location flows of people. 我有一些表的组合,用于描述人员的位置流。 The main 'travel_flows' tables has a structure as seen in the first table below.
主“ travel_flows”表的结构如下面的第一个表所示。 The order of the flows is described by the 'order_id' column.
流的顺序由“ order_id”列描述。
+-----------+------------+---------+-------------+----------+ | travel_id | purpose_id | name_id | location_id | order_id | +-----------+------------+---------+-------------+----------+ | 434 | 23 | 55 | 85 | 1 | | 212 | 43 | 55 | 45 | 2 | | 411 | 41 | 55 | 17 | 3 | | 148 | 23 | 32 | 32 | 1 | | 153 | 11 | 32 | 19 | 2 | +-----------+------------+---------+-------------+----------+
What I am trying to achieve using PostgreSQL 9.6 is to group the returned rows by 'name_id' in a binary origin(from)/destination(to) format based on 'location_id' and 'order_id' value, similar to the following table: 我试图使用PostgreSQL 9.6实现的是基于'location_id'和'order_id'值以二进制origin(from)/ destination(to)格式将返回的行按'name_id'分组,类似于下表:
+-----------------+--------------+------------------+---------------+------------+----------------+ | from_purpose_id | from_name_id | from_location_id | to_purpose_id | to_name_id | to_location_id | +-----------------+--------------+------------------+---------------+------------+----------------+ | 23 | 55 | 85 | 43 | 55 | 45 | | 43 | 55 | 45 | 41 | 55 | 17 | | 23 | 32 | 32 | 11 | 32 | 19 | +-----------------+--------------+------------------+---------------+------------+----------------+
Is there any way to achieve this with a select statement? 有什么方法可以通过select语句实现这一目标吗?
You can do this with lead
window function. 您可以使用
lead
窗口功能执行此操作。
select * from (
select purpose_id,name_id,location_id,
lead(purpose_id) over(partition by name_id order by order_id) as to_purpose_id,
lead(name_id) over(partition by name_id order by order_id) as to_name_id,
lead(location_id) over(partition by name_id order by order_id) as to_location_id
from tbl
) t
where to_purpose_id is not null and to_name_id is not null and to_location_id is not null
You can easily achieve this with Window Functions (see https://www.postgresql.org/docs/current/static/tutorial-window.html ), specifically, function lead()
: 您可以使用“窗口函数”(请参见https://www.postgresql.org/docs/current/static/tutorial-window.html )轻松实现此目的,尤其是函数
lead()
:
with flow as (
select
name_id,
purpose_id as from_purpose_id,
lead(purpose_id) over w1 as next_purpose_id,
location_id as from_location_id,
lead(location_id) over w1 as next_location_id,
order_id
from travel_flows
window w1 as (partition by name_id order by order_id)
)
select
name_id, from_purpose_id, next_purpose_id, from_location_id, next_location_id
from flow
where next_purpose_id is not null
order by name_id, order_id
;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.