多个连接表上的聚合函数

2023-12-13

我有三张桌子:

CREATE TABLE foo (
    id bigint PRIMARY KEY,
    name text NOT NULL
);

CREATE TABLE foo_bar (
    id bigint PRIMARY KEY,
    foo_id bigint NOT NULL
);

CREATE TABLE tag (
    name text NOT NULL,
    target_id bigint NOT NULL,
    PRIMARY KEY (name, target_id)
);

我正在尝试创建一个视图,以便获取表的所有字段foo, 中的项目数foo_bar where foo.id = foo_bar.foo_id,以及所有标签的文本数组,其中foo.id = tag.target_id。如果我们有:

INSERT INTO foo VALUES (1, 'one');
INSERT INTO foo VALUES (2, 'two');
INSERT INTO foo_bar VALUES (1, 1);
INSERT INTO foo_bar VALUES (2, 1);
INSERT INTO foo_bar VALUES (3, 2);
INSERT INTO foo_bar VALUES (4, 1);
INSERT INTO foo_bar VALUES (5, 2);
INSERT INTO tag VALUES ('a', 1);
INSERT INTO tag VALUES ('b', 1);
INSERT INTO tag VALUES ('c', 2);

结果应该返回:

foo.id    | foo.name     | count       | array_agg
--------------------------------------------------
1         | one          | 3           | {a, b}
2         | two          | 2           | {c}

这是我到目前为止所拥有的:

SELECT DISTINCT f.id, f.name, COUNT(b.id), array_agg(t.name)
FROM foo AS f, foo_bar AS b, tag AS t
WHERE f.id = t.target_id AND f.id = b.foo_id
GROUP BY f.id, b.id;

这些是我得到的结果(注意count是不正确的):

foo.id    | foo.name     | count       | array_agg
--------------------------------------------------
1         | one          | 2           | {a, b}
2         | two          | 1           | {c}

The count始终是标签的计数,而不是不同的计数foo_bar价值观。我尝试过重新排序/修改GROUP BYSELECT返回不同结果但不是我正在寻找的结果的子句。我想我遇到了麻烦array_agg()功能,但我不确定是否是这种情况或如何解决它。


SELECT f.id, f.name, b.fb_ct, t.tag_names
FROM   foo f
LEFT JOIN  (
    SELECT foo_id AS id, count(*) AS fb_ct
    FROM   foo_bar
    GROUP  BY 1
    ) b USING (id)
LEFT JOIN  (
    SELECT target_id AS id, array_agg(name) AS tag_names
    FROM   tag
    GROUP  BY 1
    ) t USING (id)
ORDER  BY f.id;

产生所需的结果。

  • 用显式重写JOIN句法。使它更容易阅读和理解(和调试)。

  • 通过加入多个1:n相关的表,行将相互相乘,产生一个笛卡尔积- 这是非常昂贵的废话。这是一个无意的CROSS JOIN通过代理。有关的:

    • 两个 SQL LEFT JOINS 产生不正确的结果
  • 为了避免这种情况,最多加入one n-表到1-聚合之前的表(GROUP BY)。您可以聚合两次,但聚合更干净、更快n- 单独的表格before将他们加入到1-table.

  • 与您原来的相反(隐含的INNER JOIN)。我用LEFT JOIN以避免丢失行foo中没有匹配的行foo_bar or tag.

  • 一旦不经意间CROSS JOIN已从查询中删除,无需添加DISTINCT任何更多 - 假设foo.id是独特的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多个连接表上的聚合函数 的相关文章

随机推荐

  • Python-根据列值将数据帧拆分为多个数据帧并用这些值命名它们[重复]

    这个问题在这里已经有答案了 我有一个大型数据集 列出了在全国不同地区销售的竞争对手产品 我希望通过使用这些新数据帧名称中的列值的迭代过程 根据区域将该数据帧拆分为其他几个数据帧 以便我可以单独处理每个数据帧 例如按价格对每个地区的信息进行排
  • Python Turtle 图形键盘命令

    有人对使用键盘命令在 python 2 7 中控制海龟图形有任何见解吗 我在这个网站和其他网站上进行了广泛的研究 觉得我正在做正确的事情 但它只是不想为我工作 以下是我到目前为止所得到的 谁能告诉我哪里出错了 from turtle imp
  • Django 模板过滤器 - 一行

    我正在寻找一个 Django 模板过滤器 它将多行结构转变为一大行 有人实施过吗 原因是 我有一个表单 form as p 创建一个多行html片段 我想创建一个javascript变量 它是一个html片段 但是当我这样做时 var ne
  • 启用和禁用 gridview 上的链接按钮

    我想根据条件在 gridview 的某些行上启用或禁用链接按钮 我可以在一行上启用 linkbutton 并在同一网格视图的另一行上禁用它吗 我的代码在这里 protected void GridView1 RowDataBound obj
  • 使用 regex_search 获取所有匹配项的索引?

    我刚刚开始学习如何使用regex用于字符串处理 C 11新功能 如果以下问题太愚蠢 请原谅我 目前我应用以下代码来获取所有匹配项的索引 string str aaabxxxaab regex rx ab vector
  • 为什么 3 和 x(被分配为 3)在 Haskell 中具有不同的推断类型? [复制]

    这个问题在这里已经有答案了 Haskell 中的类型推断有一点学习曲线 至少可以这么说 开始学习它的一个好方法是通过简单的例子 因此 以下是类型推断的 hello world 考虑以下示例 Prelude gt t 3 3 Num t gt
  • 无符号整数溢出

    将会发生什么unsigned int当我溢出它时包含它 具体来说 我想与两个相乘unsigned ints 里面会有什么unsigned int乘法完成后 unsigned int someint 253473829 13482018273
  • 为什么不能使用 memcmp() 函数比较浮点类型?

    bool floatcmp const float a const float b const void p void a const void q void b if memcmp p q sizeof float 0 return tr
  • 如何使我的自定义类型与“基于范围的 for 循环”一起使用?

    像现在很多人一样 我一直在尝试 C 11 带来的不同功能 我最喜欢的之一是 基于范围的 for 循环 我明白那个 for Type v a 相当于 for auto iv begin a iv end a iv Type v iv 然后be
  • 在另一个接口中使用 Typescript 接口的一个属性

    假设我有一个 Typescript 接口 如下所示 export interface IMyObj id string type AA AZ XY 现在我需要另一个也有这个接口type field export interface IMyO
  • 释放 (vfree-ing) 指向易失性数据的指针

    volatile似乎是每个人永无止境的问题 我以为我已经知道了一切 但后来我遇到了这个 所以 我有一块在线程之间共享的内存 我这样定义它 volatile type name 如果这让你感觉好一点 你可以想象type只是一个int 这意味着
  • Singleton 实现中的按需初始化惯用法与简单静态初始化器

    当使用静态初始化实现线程安全单例时 Initialize On Demand 习惯是否真的有必要 或者实例的简单静态声明就足够了 将实例简单声明为静态字段 class Singleton private static Singleton i
  • 为什么 gems 安装在与我运行的 Ruby 版本不同的目录中?

    当我安装 gem 时 它会安装在名为 1 9 1 的目录中 尽管这不是我安装的 Ruby 版本 ruby v ruby 1 9 3p327 2012 11 10 revision 37606 x86 64 darwin12 2 0 gem
  • Objective-C 中的继承和类别有什么区别

    有人可以向我解释一下 Objective C 中类别和继承之间的区别吗 我读了维基百科中的条目那里关于类别的讨论看起来与继承的讨论没有任何不同 我也看了 开放iPhone开发 一书中关于该主题的讨论 仍然不明白 有时 继承似乎比它的价值更麻
  • 使弹性项目从下到上

    以下 HTML 和 CSS 创建一个 条形图 但图表列从上到下增长 怎样才能让它们从下往上生长呢 box sizing border box font size 0 text align center line height 50px ba
  • 以编程方式在Android日历中添加提醒? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在Android中添加日历事件 我们如何在Android日历中添加提醒数据 这是我用于 ICS 的一个类 import android app Activity import android co
  • 将 .exe 文件集成到 Visual Studio 项目中

    破碎的场景 我有一个 C 程序 它在 cmd 中调用 exe 使用 process start 传递一些必需的参数 我想做的 将 exe 包含到项目中 这样我就不必调用 cmd 任何想法 如果您只是想包含这样就不必发送两个文件 那么只需将其
  • setinterval() 和clearinterval() - 清除后,不会自动设置动画

    所以我正在尝试构建一个动画背景图像 它将循环显示一组图像 这个想法还在于 当您单击页面上的任何导航元素时 循环将会暂停 当您单击主页按钮时 循环将再次启动 从当前图像开始 这在当前状态下有效 但是重新启动时循环不会自动进行 而是您必须按主页
  • 需要在 jquery mobile 中刷新页面

    我在使用 jquery mobile 时面临一些问题 当我从第一页移动到第二页时 它没有显示第二页 因为它应该是我每次都需要刷新我的页面 看起来它最初缺少一些 CSS 类 我不明白为什么会发生这种情况 我在用http code jquery
  • 多个连接表上的聚合函数

    我有三张桌子 CREATE TABLE foo id bigint PRIMARY KEY name text NOT NULL CREATE TABLE foo bar id bigint PRIMARY KEY foo id bigin