【问题标题】:PostgreSQL - How to select every second line of a group function?PostgreSQL - 如何选择组函数的每隔一行?
【发布时间】:2019-01-22 16:11:25
【问题描述】:

假设我有两个表,帖子和用户,我想要的是选择每个用户的第二个帖子(每个帖子都有它的日期,所以我可以订购)。

我已经阅读了有关偏移量和限制的信息,但它们都没有解决我的问题(至少没有我尝试过的方式)。我确实认为我正在寻找某种组功能,因为它需要在每个组(1 个用户 - N 个帖子)中工作,而不仅仅是在最终输出中。

我正在使用内连接来选择组合数据。

有人可以帮帮我吗?

表格

user_id   post_id       date         post_name
  1          1       2018-01-01       post 1
  1          2       2018-02-02       post 2
  1          3       2018-03-03       post 3
  2          4       2018-01-01       post 1
  2          5       2018-02-02       post 2
  2          6       2018-03-03       post 3
  3          7       2018-01-01       post 1
  3          8       2018-02-02       post 2
  3          9       2018-03-03       post 3
  4          10      2018-03-03       post 1

预期结果

user_id   post_id       date         post_name
   1          2       2018-02-02       post 2
   2          5       2018-02-02       post 2
   3          8       2018-02-02       post 2
   4         null        null           null

**当用户没有第二个帖子时,必须设置值“null”。

【问题讨论】:

  • 您使用的是什么查询?
  • 我正在尝试这样的事情:SELECT u.id "user id", u.name, u.email, p.id "post id", p.date, COUNT(*) FROM sql_test .post p INNER JOIN sql_test.user u ON u.id = p.user_id WHERE u.id = 1 GROUP BY (u.id, u.name, u.email, p.id, p.date) ORDER BY p.日期偏移量 1 行仅获取下 2 行;

标签: sql database postgresql join


【解决方案1】:
SELECT DISTINCT A.user_id,
(SELECT Users.post_id FROM Users WHERE Users.user_id = A.user_id AND Users.post_name = 'post 2') post_id,
(SELECT Users.date FROM Users WHERE Users.user_id = A.user_id AND Users.post_name = 'post 2') date,
(SELECT Users.post_name FROM Users WHERE Users.user_id = A.user_id AND Users.post_name = 'post 2') post_name
FROM Users AS A

http://www.sqlfiddle.com/#!15/cc0b4/17

或者你可以使用

SELECT *
FROM Users
WHERE post_name = 'post 2'
UNION
SELECT user_id, null, null, null
FROM Users
GROUP BY user_id
HAVING COUNT(*) < 2

http://www.sqlfiddle.com/#!15/cc0b4/21

【讨论】:

    【解决方案2】:

    使用row_numbersub-query

    select * from
    (
    select *,row_number() over(partition by user_id   order by date) as rn from tablea
    ) as t
    where rn =2
    

    http://www.sqlfiddle.com/#!15/3636a/2

    根据输出我更改了​​我的查询

    select * from
    (
    select *,row_number() over(partition by user_id   order by date) as rn from t
    ) as t
    where rn =2
    union
    select t1.*,null,null,null,null from
    (select user_id from t group by user_id having count(*)=1 ) as t1
    

    http://sqlfiddle.com/#!15/ee032/6

    【讨论】:

    • 你能帮我做一件事吗?如何为那些没有第二个帖子的用户显示“null”?有可能吗?
    • @G.R. sqlfiddle.com/#!15/b5210/1不客气。请不要重复发帖。如果对您有用,请接受此答案(单击复选框)...
    • @G.R.我改变了我的答案,请检查
    • @G.R.无需双发
    • @G.R.如果有帮助,请接受答案作为赞赏
    【解决方案3】:

    你会使用row_number():

    select t.*
    from (select t.*, row_number() over (partition by user_id order by date) as seqnum
          from t
         ) t
    where seqnum % 2 = 0;
    

    【讨论】:

      猜你喜欢
      • 2016-02-25
      • 1970-01-01
      • 2013-05-05
      • 2012-05-31
      • 1970-01-01
      • 2015-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多