Sql 在联接查询中使用限制/偏移

Sql 在联接查询中使用限制/偏移,sql,postgresql,Sql,Postgresql,我有四张桌子 用户帐户 user_id | username | password ---------+----------+---------- 项目表 project_id | project_name | category_id ------------+------------------------------+------------- 用户项目表(多对多关系) 项目\消息表(一个项

我有四张桌子

  • 用户帐户

    user_id | username | password                           
    ---------+----------+----------
    
  • 项目表

     project_id |         project_name         | category_id 
     ------------+------------------------------+-------------
    
  • 用户项目表(多对多关系)

  • 项目\消息表(一个项目将有许多消息)

  • 在登录时,我正在运行一个查询,使用下面的查询获取用户所属项目的数量以及每个项目的消息

    SELECT account.user_id,account.username,
           array_agg(json_build_object('message',project_messages.message,'username',project_messages.username)) AS messages,
    project.project_name 
    FROM account 
      JOIN accounts_projects ON account.user_id  = accounts_projects.account_id
      JOIN project_messages ON accounts_projects.project_id = project_messages.project_id
      JOIN project ON project.project_id = accounts_projects.project_id
    WHERE account.username=$1 
    GROUP BY project.project_name,account.user_id
    
    这给了我下面的输出

    userid,username, messages (json array object),project_name`
    87;"kannaj";"{"{\"message\" : \"saklep\", \"username\" : \"kannaj\"}"}";"Football with Javascript"
    87;"kannaj";"{"{\"message\" : \"work\", \"username\" : \"kannaj\"}","{\"message\" : \"you've been down to long in the midnight sea\", \"username\" : \"kannaj\"}","{\"message\" : \"Yeaaaa\", \"username\" : \"house\"}"}";"Machine Learning with Python"
    87;"kannaj";"{"{\"message\" : \"holyy DIVVEERRR\", \"username\" : \"kannaj\"}"}";"Beethoven with react"
    

    在从project_messages表检索消息时,有没有一种方法可以使用LIMIT/OFFSET函数?

    为了简化我们的示例,假设我们有两个链接表:

    t1(id);
    t2(id, t1_id);
    
    查询是

    select t1.id, array_agg(t2.id)
    from t1 join t2 on (t1.id = t2.t1_id)
    group by t1.id;
    
    正如您所看到的,它是大型查询的一个非常简化的变体

    1) 阵列

    此查询与原始查询一样,但仅从数组的3、4和5个元素返回,这些元素等于
    offset 2 limit 3

    2) 子查询和
    lateral

    select
      t1.id,
      array_agg(t.x)
    from
      t1 join lateral 
        (select t2.id as x from t2 where t1.id = t2.t1_id order by t2.id desc offset 2 limit 3) t on (true)
    group by t1.id;
    

    此处
    lateral
    关键字允许使用子查询(
    t1.id
    )中主
    from
    子句中提到的其他表中的字段。

    使用子查询或使用类似
    (array\u agg(…))[3:5]的子数组引发语法错误:(…我应该将子查询放在哪里?@Elad It限制整个表,而不是每个组。@Elad-这会限制整个输出的行数,而不是列的行数。是否有更好的方法可以运行查询?我是否在其他地方出错?我在使用切片运算符时遇到语法错误。
    error:syntax error at或near“[”
    :(…当有其他连接时,我似乎不能使用横向关键字..我缺少什么吗?@Kunkka 1)将整个
    数组_agg
    函数括在括号中:
    (数组_agg(…)[n:m]
    2)检查我的编辑,它更容易理解。现在可以工作了:)…我现在有另一个问题..是否有办法也包括ORDER BY条款?谢谢..我实际上读了一些横向..我认为你的第二个例子更灵活..你说呢?@Kunkka Flexibility几乎是一样的。第二个例子在性能方面可能更有效。这取决于你选择哪一个用于您的任务。
    select t1.id, array_agg(t2.id)
    from t1 join t2 on (t1.id = t2.t1_id)
    group by t1.id;
    
    select t1.id, (array_agg(t2.id order by t2.id desc))[3:5]
    from t1 join t2 on (t1.id = t2.t1_id)
    group by t1.id;
    
    select
      t1.id,
      array_agg(t.x)
    from
      t1 join lateral 
        (select t2.id as x from t2 where t1.id = t2.t1_id order by t2.id desc offset 2 limit 3) t on (true)
    group by t1.id;