Postgres LEFT JOIN 与 SUM,丢失记录

2023-12-19

我正在尝试获取相关表中某些类型记录的计数。我正在使用左连接。

因此,我有一个不太正确的查询,但返回了正确的结果。正确的结果查询具有更高的执行成本。如果我可以纠正结果,我想使用第一种方法。 (看http://sqlfiddle.com/#!15/7c20b/5/2 http://sqlfiddle.com/#!15/7c20b/5/2)

CREATE TABLE people(
  id SERIAL,
  name varchar not null
);

CREATE TABLE pets(
  id SERIAL,
  name varchar not null, 
  kind varchar not null,
  alive boolean not null default false,
  person_id integer not null
);

INSERT INTO people(name) VALUES
('Chad'),
('Buck'); --can't keep pets alive

INSERT INTO pets(name, alive, kind, person_id) VALUES
('doggio', true, 'dog', 1),
('dog master flash', true, 'dog', 1),
('catio', true, 'cat', 1),
('lucky', false, 'cat', 2);

我的目标是找回一张桌子,上面有所有的人以及他们所养宠物的种类:

| ID | ALIVE_DOGS_COUNT | ALIVE_CATS_COUNT |
|----|------------------|------------------|
|  1 |                2 |                1 |
|  2 |                0 |                0 |

我把这个例子变得更简单了。在我们的生产应用程序(不是真正的宠物)中,每人大约有 100,000 只死狗和猫。我知道这很糟糕,但这个例子更容易转发;)我希望在计数之前过滤掉所有“死”的东西。我现在在生产中的查询速度较慢(来自上面的 sqlfiddle),但希望 LEFT JOIN 版本能够正常工作。


如果您获取,通常最快所有或大多数行:

SELECT pp.id
     , COALESCE(pt.a_dog_ct, 0) AS alive_dogs_count
     , COALESCE(pt.a_cat_ct, 0) AS alive_cats_count
FROM   people pp
LEFT   JOIN (
   SELECT person_id
        , count(kind = 'dog' OR NULL) AS a_dog_ct
        , count(kind = 'cat' OR NULL) AS a_cat_ct
   FROM   pets
   WHERE  alive
   GROUP  BY 1
   ) pt ON pt.person_id = pp.id;

索引在这里无关紧要,全表扫描将是最快的。Except如果活着的宠物是rare情况下,那么一个部分索引 http://www.postgresql.org/docs/current/interactive/indexes-partial.html应该有帮助。喜欢:

CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;

我包含了查询所需的所有列(person_id, kind)允许仅索引扫描。

SQL 小提琴。 http://sqlfiddle.com/#!15/78baa/2

通常最快的小子集或单行:

SELECT pp.id
     , count(kind = 'dog' OR NULL) AS alive_dogs_count
     , count(kind = 'cat' OR NULL) AS alive_cats_count
FROM   people pp
LEFT   JOIN pets pt ON pt.person_id = pp.id
                   AND pt.alive
WHERE  <some condition to retrieve a small subset>
GROUP  BY 1;

你至少应该有一个索引pets.person_id为此(或上面的部分索引) - 可能还有更多,具体取决于WHERE健康)状况。

相关回答:

  • 使用 LEFT JOIN 的查询不返回计数为 0 的行 https://stackoverflow.com/questions/15467624/count-on-left-join-not-returning-0-values/15468034#15468034
  • JOIN 返回重复项后的 GROUP 或 DISTINCT https://stackoverflow.com/questions/25486942/group-or-distinct-after-join-returns-duplicates/25487898#25487898
  • 获取多个表中外键的数量 https://stackoverflow.com/questions/24745091/get-count-of-foreign-key-from-multiple-tables/24747523#24747523
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Postgres LEFT JOIN 与 SUM,丢失记录 的相关文章

随机推荐

  • 任何巧妙的方法来修复 LINQ 的“字符串或二进制数据将被截断”警告

    有没有一种巧妙的方法来确定哪个字段导致 字符串或二进制数据将被 LINQ 截断 我总是通过逐步调试器来手动完成此操作 但是对于使用 SubmitChanges 的批处理 我必须更改代码以插入单行以在一批行中找到罪魁祸首 我是否遗漏了某些东西
  • Android 未签名应用程序无法安装在设备上

    我的应用程序可以在模拟器上运行 并将其导出为未签名的应用程序 在我的手机设置 gt gt 应用程序 gt gt 检查了未知来源 我通过 USB 将 apk 下载到手机存储中 然后在文件管理器下 我发现存储了 apk 并点击安装按钮 它尝试安
  • $watchGroup 与 $watchCollection?

    有观察一组变量的 2 种方法 https docs angularjs org api ng type 24rootScope Scope在角度 但它们之间有什么区别呢 他们似乎都做浅表 是否存在其中一种明显优于另一种的情况 watchCo
  • App Engine 部署:获取应用程序的权限错误

    我们使用服务帐户通过 Travis 将我们的应用程序部署到 App Engine 在每个合并的 PR 中 Travis 从我们的 GitHub 存储库中提取代码 并提取Docker镜像 https github com hollowvers
  • 如何使用 onFieldSubscribed 单独验证 TextFormField

    我正在制作一个自定义 TextFormField 小部件 它将被多次使用 如何验证单个 TextFormField 而不验证同一列表 行 列中的任何其他 TextFormField Widget timeTextField TextEdit
  • 为什么绘图渲染的图表在 Mozilla 上不起作用

    当我尝试在 Mozilla Firefox 中打开与knitr 放在一起的 html 文档时 出现以下错误 该错误是由以下图形元素组成的结果plotly包裹 unknownError error occurred while process
  • 在 Internet Explorer 中意外调用 JQuery UI Autocomplete focus()

    我使用 JQuery UI 创建了一个简单的自动完成控件 我的输入字段有一个默认值 输入您的关键字 我已经设置了一个focus 当用户将焦点设置到要键入的输入字段时 该事件将清除输入 在 IE 中 当您键入并且菜单显示项目列表时 当从菜单项
  • 枚举的字符串表示(estring)?

    我需要一个枚举或类似的东西来做这样的事情 公共枚举 MyStringEnum StringValue Foo A Foo A StringValue Foo B Foo B 这可能吗 我的示例 我返回一个数据集 其值表示为 A B C D
  • 在 Clojure REPL 中使用自定义 Java 类

    在 Eclipse 中 使用 CCW 插件 我想将 clojure 文件加载到 REPL 中 问题是我有一个我自己的 java 类的 import 语句 但显然它不在我的类路径中 ns my clj ns import alg gen En
  • 如何将 Flyway 迁移与单个模式和多个项目一起使用

    如何管理处理相同数据库模式的多个项目 每个项目中的Flyway迁移脚本如果被其他项目修改则不允许启动 例如 我有一个带有 FlywayInitializer 类的 Spring Boot Project X PostConstruct pu
  • Javamail 无法将套接字转换为 TLS GMail

    我正在尝试使用 JavaMail 通过 Gmail SMTP 服务器发送电子邮件 这是代码 final String username email protected cdn cgi l email protection final Str
  • IISExpress应用程序池回收

    有没有办法回收 IIS Express 应用程序池 如果我打开 cmd 并转到C Program Files IIS Express 然后运行 appcmd apppool 命令列表缺少 回收 选项 我发现的唯一解决方法是编辑applica
  • C++ realloc 性能 vs malloc

    首先 我知道我错了 但我不知道我的错是什么 根据这个链接 http www cplusplus com reference cstdlib realloc 关于 realloc 它说 即使该块被移动到新位置 内存块的内容也会保留到新大小和旧
  • 每秒请求数和响应时间之间的相关性?

    有人可以解释一下每秒请求数和响应时间之间的相关性吗 您首先想改进哪一方面 如果您的竞争对手在其最常用的功能上提供的 每秒请求数 较少 那么您的应用程序在最终用户性能方面是否表现更好 有人可以解释一下每秒请求数和响应时间之间的相关性吗 将这种
  • 无法写入核心转储。核心转储已被禁用

    我一直在从事一个视觉项目 并通过 JNI 在 Java 中使用一些 C 库 OS 乌班图12 04 在我的项目中 我使用boost http www boost org 库来生成随机数 但有时我会遇到如下异常 Core dum1400023
  • 如何禁用片段中的抽屉并返回到正确的片段

    我有一个带有片段布局的主要活动 抽屉有3种选择 Fragment 1 Fragment 2 Fragment 3 Fragment 2 和Fragment 3 里面是一个按钮 此按钮打开其他片段 片段 4 我想要没有抽屉但有后退按钮的 Fr
  • ASP.Net 计数下载点击次数

    我以为这更容易 我有一个 asp hyperlink 控件 带有target blank 指向我希望用户下载的文件 我的计划是跟踪用户点击此链接的次数 我想将它放在 ajax 更新面板中 以捕获回发并避免全页刷新 然而 超链接没有onCli
  • 将时间 API 从 Linux 移植到 Visual Studio 2008

    我有一个应用程序正在移植到 Microsoft Visual Studio 2008 该应用程序可以在 Linux 上正常构建和运行 我在时间例程方面遇到了麻烦 我的 Linux 代码如下所示 include
  • 如何修复“npm ERR!在您的 package-lock.json 中发现错误”

    我在 npm 中收到以下错误 请问这是什么意思 我该如何修复此错误 npm ERR code ELOCKVERIFY npm ERR Errors were found in your package lock json run npm i
  • Postgres LEFT JOIN 与 SUM,丢失记录

    我正在尝试获取相关表中某些类型记录的计数 我正在使用左连接 因此 我有一个不太正确的查询 但返回了正确的结果 正确的结果查询具有更高的执行成本 如果我可以纠正结果 我想使用第一种方法 看http sqlfiddle com 15 7c20b