在Postgres中使用ANY内部的ANY条款?

时间:2015-08-24 13:24:21

标签: postgresql

我们说我有以下架构:

CREATE TABLE author(
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL
);

CREATE TABLE article(
  id SERIAL PRIMARY KEY,
  rating    NUMERIC NOT NULL,
  author_id INTEGER NOT NULL REFERENCES author
);

CREATE INDEX ON article(author_id);

我想获取所有作者及其前五篇文章,如果至少有一篇作者评论> 4。

很有可能写这个:

SELECT au.id AS author,
       json_agg(ar.*) AS articles
FROM
    author au
JOIN LATERAL
  (SELECT *
   FROM article
   WHERE author_id = au.id
   ORDER BY rating DESC LIMIT 5) ar ON (TRUE)
GROUP BY au.id
HAVING any(ar.rating) > 4;

虽然any(ar.rating) > 4看起来像是每个组的过滤器表达式,但any(ar.rating)不是聚合值。因此,Postgres拒绝此查询似乎是合理的。是否可以使用HAVING编写查询?

作为替代方案,我编写此查询以获取结果:

SELECT au.id AS author,
       json_agg(ar.*) AS articles
FROM
  (SELECT au.*
   FROM author au
   WHERE EXISTS
       (SELECT 1
        FROM article
        WHERE rating > 4 AND author_id = au.id)) au
JOIN LATERAL
  (SELECT *
   FROM article
   WHERE author_id = au.id
   ORDER BY rating DESC LIMIT 5) ar ON (TRUE)
GROUP BY au.id;
然而,这并没有结合分组和检查是否存在具有评级>的文章。 4步一步完成。有没有更好的方法来编写此查询?

1 个答案:

答案 0 :(得分:2)

如果您坚持使用ANY,则必须使用array_agg将该列聚合为数组。

HAVING 
  4< ANY(Array_Agg(ar.rating))

但如果任何高于4,则也意味着最大值高于4,因此更具可读性

HAVING
  4 < Max(ar.rating)