如果不满足条件,如何在array_agg 中获取空数组?

问题描述

我有 2 张桌子:

collections_books (collection_id,book_id)
users_collections (user_id,collection_id,access)

我正在使用 Postgresql

以下查询为我提供了按 book_id 分组的 collection_id 列表。问题是,由于我使用 where 条件,结果仅限于 allowed 为 user_id = 3 的集合。

但是,我想要所有的 collection_id 和相应的 book_id

  1. 作为数组,如果 user_id 有 access = allow
  2. 作为空数组,如果 user_id 不存在于 users_collectionsuser_id != allow
SELECT c.collection_id,ARRAY_AGG(c.book_id)
FROM collections_books AS c
LEFT JOIN users_collections AS u
ON c.collection_id = u.collection_id
WHERE 
  u.access = 'allow' AND
  u.user_id = 3
GROUP BY c.collection_id;

解决方法

您检查 array_length()。如果它小于 1,则返回一个值为 {null}

的数组

如果您想从 collections_books 中获取所有 collection_id 但仅当 u.access = 'allow' AND u.user_id = 4 时才获取 book_id 数组,否则为 null 则使用以下查询:

SELECT c.collection_id,(
        CASE 
             WHEN max(u.access) = 'allow' AND max(u.user_id) = 4
             THEN ARRAY_AGG(c.book_id)
             ELSE '{null}'::int[] 
        END
    )
    FROM collections_books AS c
    LEFT JOIN users_collections AS u
    ON c.collection_id = u.collection_id
    GROUP BY c.collection_id;
,

请查看下面的答案,让我知道它是否返回您想要的输出:

架构和插入语句:

     create table users_collections (user_id int,collection_id int,access varchar(20));
     insert into users_collections values(3,1,'allow');
     insert into users_collections values(3,2,'allow');
     insert into users_collections values(4,3,5,'not allow');

 
     create table collections_books (collection_id int,book_id int);
     insert into collections_books values(2,24);
     insert into collections_books values(3,35);
     insert into collections_books values(3,25);
     insert into collections_books values(1,36);
     insert into collections_books values(1,22);
     insert into collections_books values(1,24);
     insert into collections_books values(2,34);
     insert into collections_books values(5,344);
     insert into collections_books values(6,474);

查询:

     SELECT c.collection_id,(CASE WHEN max(u.access) = 'allow' AND max(u.user_id) = 3
     THEN ARRAY_AGG(c.book_id)
     ELSE '{null}'::int[] END)
     FROM collections_books AS c
     LEFT JOIN users_collections AS u
     ON c.collection_id = u.collection_id
     GROUP BY c.collection_id;
 

输出:

 |collection_id | case      |
 |------------: | :---------|
 |            3 | {35,25}   |
 |            5 | {NULL}    |
 |            6 | {NULL}    |
 |            2 | {24,34}   |
 |            1 | {36,24,22}|

dbhere