我试图编写一个SQL查询,它有能力检查某个数据是否存在于聚合数据范围内,我在查询中使用了ARRAY_AGG函数。
以下是架构的外观:

Schema Browser
----------------------------
  + post (TABLE)
      postid int4(10)
      name varchar(5)

  + posttag (TABLE)
      posttagid int4(10)
      postid int4(10)
      tagid int4(10)

  + tag (TABLE)
      tagid int4(10)
      name varchar(20)

下面是我使用ARRAY_AGG获取所有带有标记的帖子的查询:
SELECT * FROM post,
LATERAL (
  SELECT
    ARRAY_AGG( DISTINCT tag.name ) AS tags
    FROM tag, posttag
    WHERE post.postid = posttag.postid
    AND posttag.tagid = tag.tagid
) posts

它将输出这个结果集,这正是我想要的:
sql - 检查汇总数据中是否存在相关数据-LMLPHP
问题是当我试图使用标签过滤器!例如,我想得到所有的帖子,其中有“节点”和“测试”标签。假设“test”标记的id为1,“node”标记的id为2。所以我正在尝试像这样的IN条件,下面是我将如何在查询中添加where条件:
SELECT * FROM post,
LATERAL (
  SELECT
    ARRAY_AGG( DISTINCT tag.name ) AS tags
    FROM tag, posttag
    WHERE post.postid = posttag.postid
    AND posttag.tagid = tag.tagid
    AND tag.tagid IN (1, 2)
) posts

但现在它会释放所有其他标签,好像所有的帖子只有两个标签,这是不正确的。还有一些空标签!
sql - 检查汇总数据中是否存在相关数据-LMLPHP
这里是游乐场。
如何简单地检查ID 1和2是否存在于ARARYAGAG中,这样它不会改变结果吗?

最佳答案

demo:db<>fiddle
WHERE子句在聚合之前过滤标记。在您的情况下,HAVING子句有助于筛选分组记录。&&数组运算符检查两个数组之间的重叠:

   SELECT * FROM post,
    LATERAL (
      SELECT
        ARRAY_AGG( DISTINCT tag.name ) AS tags
        FROM tag, posttag
        WHERE post.postid = posttag.postid
        AND posttag.tagid = tag.tagid
        HAVING ARRAY[1,2] && ARRAY_AGG(DISTINCT tag.tagid)
    ) posts

结果:
postid | name  | tags
-----: | :---- | :------------------
     1 | hello | {go,node,rust,test}
     2 | world | {node,test}

关于sql - 检查汇总数据中是否存在相关数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57213879/

10-12 17:30
查看更多