在PostgreSQL中仅返回其字符串数组中包含指定字符串的行

时间:2019-02-06 21:15:03

标签: postgresql

我想在PostgresSQL的字符串数组中获取所有具有特定值(或一组值)的记录组。例如,取下表

+---------+------------+--------+
| user_id |    date    | group  |
+---------+------------+--------+
|       1 | 2019-02-06 | groupA |
|       1 | 2019-02-06 | groupB |
|       1 | 2019-02-06 | groupC |
|       2 | 2019-02-06 | groupB |
|       2 | 2019-02-06 | groupC |
|       3 | 2019-02-06 | groupA |
|       3 | 2019-02-06 | groupC |
+---------+------------+--------+

我可以使用以下查询将它们分组:

SELECT
   user_id,
   date,
   string_agg(group, ',') as groups
FROM t
GROUP BY
   user_id,
   date

给出以下内容;

+---------+------------+-------------------------+
| user_id |    date    |         groups          |
+---------+------------+-------------------------+
|       1 | 2019-02-06 |  {groupA,groupB,groupC} |
|       2 | 2019-02-06 |  {groupB,groupC}        |
|       3 | 2019-02-06 |  {groupA,groupC}        |
+---------+------------+-------------------------+

但是我只希望包含groupA的组。也就是说,这是所需的输出:

+---------+------------+-------------------------+
| user_id |    date    |         groups          |
+---------+------------+-------------------------+
|       1 | 2019-02-06 |  {groupA,groupB,groupC} |
|       3 | 2019-02-06 |  {groupA,groupC}        |
+---------+------------+-------------------------+

如何过滤出不包含groupA的行?

这是我尝试失败的一个查询:

SELECT
   user_id,
   date,
   string_agg(group, ',') as groups
FROM t
GROUP BY
   user_id,
   date
HAVING 'groupA' IN string_agg(group, ',')

1 个答案:

答案 0 :(得分:1)

IN不能与元素列表一起使用,string_agg()返回单个字符值。

但是您可以将值聚合到可以在hading子句中使用的数组中:

SELECT user_id,
       "date",
       string_agg("group", ',') as groups
FROM t
GROUP BY user_id, "date"
HAVING 'groupA' = any (array_agg("group"));

另一种选择是使用contains operator @>

SELECT user_id,
       "date",
       string_agg("group", ',') as groups
FROM t
GROUP BY user_id, date
HAVING array_agg("group") @> array['groupA']::varchar[]