有2个表,users
和job_experiences
。
我想返回除与每个用户相关的第一个job_experiences
之外的所有列表。
用户
id
---
1
2
3
job_experiences
id | start_date | user_id
--------------------------
1 | 201001 | 1
2 | 201201 | 1
3 | 201506 | 1
4 | 200901 | 2
5 | 201005 | 2
所需结果
id | start_date | user_id
--------------------------
2 | 201201 | 1
3 | 201506 | 1
5 | 201005 | 2
当前查询
select
*
from job_experiences
order by start_date asc
offset 1
但这不起作用,因为它需要将偏移量分别应用于每个用户。
答案 0 :(得分:1)
使用row_number()
窗口功能
with cte as
(
select e.*,
row_number()over(partition by user_id order by start_date desc) rn,
count(*) over(partition by user_id) cnt
from users u join job_experiences e on u.id=e.user_id
)
, cte2 as
(
select * from cte
) select * from cte2 t1
where rn<=(select max(cnt)-1 from cte2 t2 where t1.user_id=t2.user_id)
答案 1 :(得分:1)
您可以通过横向联接来做到这一点:
select je.*
from users u cross join lateral
(select je.*
from job_experiences je
where u.id = je.user_id
order by id
offset 1 -- all except the first
) je;
为了提高性能,建议在job_experiences(user_id, id)
上使用索引。
答案 2 :(得分:0)
您可以使用中间CTE为每个用户获取第一个(MIN
)作业,然后使用该值确定要排除的记录:
WITH user_first_je("user_id", "job_id") AS
(
SELECT "user_id", MIN("id")
FROM job_experiences
GROUP BY "user_id"
)
SELECT job_experiences.*
FROM job_experiences
LEFT JOIN user_first_je ON
user_first_je.job_id = job_experiences.id
WHERE user_first_je.job_id IS NULL;