【问题标题】:Exclude first record associated with each parent record in Postgres排除与 Postgres 中每个父记录关联的第一条记录
【发布时间】:2019-03-11 18:43:26
【问题描述】:

有 2 个表,usersjob_experiences

我想返回除与每个用户关联的第一个job_experiences 之外的所有job_experiences 的列表。

用户

id 
---
1
2
3

工作经验

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

但这不起作用,因为它需要将偏移量单独应用于每个用户。

【问题讨论】:

    标签: sql postgresql offset


    【解决方案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) 上的索引。

    【讨论】:

    • 这对于大量记录来说真的很慢。有什么想法可以加快速度吗?
    • @tim_xyz 。 . .谢谢。
    【解决方案2】:

    使用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)
    

    【讨论】:

      【解决方案3】:

      您可以使用中间 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;
      

      【讨论】:

        猜你喜欢
        • 2010-09-23
        • 1970-01-01
        • 2016-02-23
        • 1970-01-01
        • 2021-08-31
        • 1970-01-01
        • 2015-04-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多