Исключить первую запись, связанную с каждой родительской записью в Postgres - PullRequest
0 голосов
/ 11 марта 2019

Есть 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

Текущийquery

select 
   * 
from job_experiences
order by start_date asc
offset 1

Но это не работает, так как необходимо применить смещение для каждого пользователя в отдельности.

Ответы [ 3 ]

1 голос
/ 11 марта 2019

Вы можете сделать это с боковым соединением:

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).

1 голос
/ 11 марта 2019

использование 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)
0 голосов
/ 11 марта 2019

Вы можете использовать промежуточный 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...