Rails 用范围扩展领域,PG 不喜欢它

2024-03-26

我有一个小部件模型。小部件属于 Store 模型,Store 模型属于 Area 模型,Area 模型属于 Company。在公司模型中,我需要找到所有关联的小部件。简单的:

class Widget < ActiveRecord::Base
  def self.in_company(company)
    includes(:store => {:area => :company}).where(:companies => {:id => company.id})
  end
end

这将生成这个漂亮的查询:

> Widget.in_company(Company.first).count

SQL (50.5ms)  SELECT COUNT(DISTINCT "widgets"."id") FROM "widgets" LEFT OUTER JOIN "stores" ON "stores"."id" = "widgets"."store_id" LEFT OUTER JOIN "areas" ON "areas"."id" = "stores"."area_id" LEFT OUTER JOIN "companies" ON "companies"."id" = "areas"."company_id" WHERE "companies"."id" = 1
 => 15088 

但是,我稍后需要在更复杂的范围中使用这个范围。问题在于 AR 通过选择单个字段来扩展查询,这在 PG 中失败,因为所选字段必须位于 GROUP BY 子句或聚合函数中。

这是更复杂的范围。

def self.sum_amount_chart_series(company, start_time)
  orders_by_day = Widget.in_company(company).archived.not_void.
                  where(:print_datetime => start_time.beginning_of_day..Time.zone.now.end_of_day).
                  group(pg_print_date_group).
                  select("#{pg_print_date_group} as print_date, sum(amount) as total_amount")

end

def self.pg_print_date_group
  "CAST((print_datetime + interval '#{tz_offset_hours} hours') AS date)"
end

这是它向 PG 抛出的选择:

> Widget.sum_amount_chart_series(Company.first, 1.day.ago)

SELECT "widgets"."id" AS t0_r0, "widgets"."user_id" AS t0_r1,<...BIG SNIP, YOU GET THE IDEA...> FROM "widgets" LEFT OUTER JOIN "stores" ON "stores"."id" = "widgets"."store_id" LEFT OUTER JOIN "areas" ON "areas"."id" = "stores"."area_id" LEFT OUTER JOIN "companies" ON "companies"."id" = "areas"."company_id" WHERE "companies"."id" = 1 AND "widgets"."archived" = 't' AND "widgets"."voided" = 'f' AND ("widgets"."print_datetime" BETWEEN '2011-04-24 00:00:00.000000' AND '2011-04-25 23:59:59.999999') GROUP BY CAST((print_datetime + interval '-7 hours') AS date)

这会产生此错误:

PGError:错误:列 “widgets.id”必须出现在 GROUP BY 子句或用于 聚合函数第 1 行:选择 “小部件”。“id”AS t0_r0, “小部件”。“user_id...

如何重写 Widget.in_company 范围,以便 AR 不会扩展选择查询以包含每个 Widget 模型字段?


正如 Frank 所解释的,PostgreSQL 将拒绝任何不返回可重现行集的查询。

假设您有如下查询:

select a, b, agg(c)
from tbl
group by a

PostgreSQL 将拒绝它,因为b中未指定group by陈述。相比之下,在 MySQL 中运行它,它将被接受。然而,在后一种情况下,启动一些插入、更新和删除,并且磁盘页面上的行的顺序最终会有所不同。

如果没记错的话,实现细节是 MySQL 实际上按 a、b 排序并返回集合中的第一个 b。但就 SQL 标准而言,行为是未指定的 —— 果然,PostgreSQL 确实如此not始终在运行聚合函数之前进行排序。

这可能会导致不同的值b在 PostgreSQL 的结果集中。因此,除非你更具体,否则 PostgreSQL 会产生错误:

select a, b, agg(c)
from tbl
group by a, b

Frank 强调的是,在 PostgreSQL 9.1 中,如果a是主键,你可以离开b未指定——当适用的主键暗示唯一行时,规划器被教导忽略后续的分组依据字段。

特别是对于您的问题,您需要像当前一样指定您的分组依据,plus您聚合的每个字段,即"widgets"."id", "widgets"."user_id", [snip]但不是类似的东西sum(amount),这是聚合函数调用。

作为一个题外话,我不确定你的 ORM/模型是如何工作的,但它生成的 SQL 并不是最佳的。许多左外连接看起来应该是内连接。这将允许规划者在适用的情况下选择适当的连接顺序。

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

Rails 用范围扩展领域,PG 不喜欢它 的相关文章

  • 如何在rails中定义自定义路径?

    我有一个用户模型 如果我做 def my action user User new end then I get undefined method users path for
  • Rails 3 中关联的标记装置已损坏

    升级到 Rails 3 后 引用其他标记的装置 用于关系 的装置将停止工作 夹具标签被解释为字符串 而不是查找具有该名称的实际夹具 Example Dog yml sparky name Sparky owner john Person y
  • 如何优化 postgres 查询

    我正在运行以下查询 SELECT fat FROM Table1 fat LEFT JOIN modo captura mc ON mc id fat modo captura id INNER JOIN loja lj ON lj id
  • 在 Ruby on Rails 中渲染部分集合正在乘以项目

    我想在 Ruby on Rails 的页面中显示项目列表 我使用部分 in my index html erb我有的文件 in list news html erb I have div class news div
  • Python 和 Postgresql:操作错误:fe_sendauth:未提供密码

    我知道 StackOverflow 上有很多类似的问题 但我已经阅读并重新阅读了它们 但我似乎无法解决我的特定问题 我正在开发一个使用 Peewee 和 Psycopg2 访问 PostGresQL 数据库的 Python 应用程序 这一切
  • 您推荐使用哪些工具来分析 Rails 应用程序? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我一直在寻找 Rails 的分析工具 我目前正在玩和测试 ruby prof 和 Railsbench 但我对使其工作所需的大量调整和修改
  • 如何让 Rails 资产管道生成源地图?

    我想让 Rails 与编译后的 CoffeeScript 缩小的 JS 一起生成源映射 以便更好地记录错误 不过 网上似乎还没有关于如何执行此操作的全面文档 有人这样做过吗 我使用 Rails 3 2 和 Heroku Rails 支持缩小
  • 单表继承发现问题

    我有以下3个rails类 它们都存储在一张表中 使用rails的单表继承 class Template lt ActiveRecord Base class ThingTemplate lt Template class StockThin
  • 如果数组重叠,则折叠多行数组

    我在 PostgreSQL 9 3 中有一个表 其中包含一个列 每行包含一个数组 我正在努力寻找崩溃的方法 共享相同元素的数组行 Examples 简单重叠 给定以下两行数组 1 2 3 5 3 6 9 结果将是一行包含 5 1 2 3 6
  • Rails 3 UJS 干客户端 + 服务器端表单验证

    使用 jQuery 进行表单验证就像向字段添加类名一样简单 使用 Rails 进行表单验证就像将条件放入控制器 和 或模型 中一样简单 我认为应该有一种方法可以编写一次验证并将它们应用到客户端和服务器端 我一直热衷于编写自己的 javasc
  • 使用 HABTM 关系更新复选框的值 -- Rails

    嘿伙计们 我一直在使用 has and belongs to many 与复选框示例的关系Railscast 第 17 集 http railscasts com episodes 17 habtm checkboxes 我遇到了一些问题
  • 在初始化程序中重新加载命名空间常量

    今天遇到一个有趣的情况 我不确定如何解决 给定一个带有初始化器的 Rails 应用程序 file config initializers integrations rb Integrations CONFIGS key gt value f
  • H2 和 PostgreSQL 兼容模式限制

    我使用 H2 数据库作为内存数据库进行测试 其中 PostgreSQL 在生产中使用 除了两者之间存在一些细微差别之外 此设置工作正常 我现在关心的一个问题是PostgreSQL 中标识符的长度限制为 64 https www postgr
  • Rails 模型中的多个 counter_cache

    我正在学习 Rails 遇到了一个小问题 我正在编写带有任务列表的非常简单的应用程序 因此模型看起来像这样 class List lt ActiveRecord Base has many tasks has many undone tas
  • Rails:从视图内渲染视图(不是部分视图)

    我有一个对两者都有响应的控制器html and js The htmlview 渲染整个页面 包括页眉和页脚 而js仅替换 main 除了页眉和页脚之外 两种格式呈现相同的内容 我可以用三个文件获得这种效果 show html erb di
  • blueprint/screen.css 未预编译

    我一直在遵循 Michael Hartl 出色的 RoR 教程 但我使用的是 RoR 3 1 我是 RoR 3 1 的新手 需要与资产管道相关的帮助 这是我的问题 在继续第 5 3 节之前 我想先转到 Heroku 看看事情如何发展 令我惊
  • 查找一列中具有相同值而另一列中具有其他值的行?

    我有一个 PostgreSQL 数据库 将用户存储在users他们参与的表格和对话conversation桌子 由于每个用户可以参与多个对话 并且每个对话可以涉及多个用户 因此我有一个conversation user链接表来跟踪哪些用户正
  • Rails - 使链接与 ajax 一起工作

    我有一个链接 应该使用 ajax 加载它旁边的部分内容 而无需重新加载页面 链接在这里 这是链接应该转到的控制器 class ProfilesController lt ApplicationController def profile f
  • Rails 模型测试 - 模拟与工厂

    Rails 测试模拟对象与使用工厂对象的最佳实践是什么 应该嘲笑only当模型可能转到外部源时使用 或者 您是否仅在测试实际模型并使用模拟来处理其他所有内容时才使用工厂 例如 如果我们有一个包含客户和订单的销售系统 那么当我们测试客户模型时
  • 如何在 typeorm 中使用 LEFT JOIN LATERAL?

    我想在 TypeOrm 中使用以下查询 但找不到将其转换为 TypeOrm 的方法 任何帮助表示赞赏 SELECT FROM blocked times bt LEFT JOIN LATERAL SELECT FROM bookings b

随机推荐

  • PHP性能考虑?

    我正在建造一个PHP网站 但目前唯一PHP我在某些页面上使用的是六个左右的包含内容 我最终可能会使用一些数据库查询 很简单include 声明关注速度或扩展 而不是静态HTML 什么样的事情容易导致网站陷入困境 当然 include 比静态
  • Activity 方法:onCreate() 和 onDestroy()

    当第一次创建活动时 系统会调用OnContentChanged 方法作为系统的第一个方法和最后一个调用是OnDetachedFromWindow 方法当一个 Activity 被杀死时 但 android 文档说 Activity 的整个生
  • 如何使用PageDown Markdown编辑器?

    我想为用户提供实时预览使用 Markdown 创建的笔记的能力 但是我在该项目中找不到任何下载 我怎样才能开始使用PageDown 降价 https github com balpha pagedown编辑 PageDown 的文档非常混乱
  • 使用 pyExcelerator/xlrd 进行数据透视

    如何使用 pyExcelerator xlrd 等 Python 库创建带有数据透视表的工作表 在 Excel 工作簿中 我需要生成一份每日报告 其中有一个数据透视表来汇总其他工作表上的数据 一种选择是使用一个空白模板 我可以复制该模板并用
  • TFS 分支和合并策略

    我在 TFS 中有一个团队项目 每天都会提交任务 我想独立完成每个任务 然后在测试后将其合并到主线中 目前有一个 MAIN 分支和一个 DEV 分支 它是 MAIN 的子分支 更改在 DEV 分支中进行 然后在准备就绪时合并到 MAIN 中
  • 什么时候应该尝试消除 switch 语句? [复制]

    这个问题在这里已经有答案了 我在我正在处理的代码库中遇到了一个 switch 语句 我正在尝试找出如何用更好的东西替换它switch 语句被认为是代码味道 http c2 com cgi wiki SwitchStatementsSmell
  • React 处理表单提交

    我正在尝试在 React Redux 中创建一个表单 现在我只希望表单在提交表单时触发我的函数handleSubmit 然而目前看来该功能是在页面加载时立即触发的 export default class AssetsAdd extends
  • Selenium:Firefox 驱动程序,在 c# 中使用 SelectElement 从下拉列表中选择一个项目无法正常工作

    我正在尝试执行一项简单的任务 尝试使用显示的文本在下拉列表中选择一个值 场景如下 我的 HTML 看起来像 div class col md 4 div
  • SQL Server 2008 中 Oracle 的 LAST_DAY() 函数的等效项是什么?

    我已经用过LAST DAY 函数 http docs oracle com cd B19306 01 server 102 b14200 functions072 htm在Oracle中是这样的 Last Day to date pay f
  • 使用 node.js 通过 Firebase-Admin 登录

    我正在尝试使用 firebase admin 使用 node js 登录 但是当我查找 API 时 他们只有关于update delete and create 他们确实有关于如何通过电子邮件获取用户的部分 但如果我想登录用户 我是否也应该
  • 在 Visual Studio 2008 中构建解决方案后,是否可以运行外部可执行文件?

    我不是在谈论项目的构建后事件 相反 我想在构建整个解决方案后自动运行可执行文件 有没有办法为解决方案执行构建后事件 Visual Studio 2010 及之前版本 您可以在宏编辑器中通过处理 OnBuildDone 来执行此操作 该事件为
  • 在模板中显示 Handlebars.js 上下文

    是否有一个变量传递到每个handlebar js 模板中 其中包含模板可访问的所有上下文内容 例如我正在创建一个模板 但我不知道该模板可访问的所有上下文内容 我希望能够在模板中输入内容 debug 并且handlebars js会将所有上下
  • 解析 XML Libxmljs (Node.js)

    我正在尝试解析 XML 字符串libxmljs https github com polotek libxmljs https github com polotek libxmljs 不过我有一些问题 我需要将逻辑应用于我正在解析的内容 并
  • 在 Javascript 中绘制可缩放的音频波形时间线

    我有来自歌曲的原始 44 1 kHz 音频数据作为 Javascript 数组 我想用它创建一个可缩放的时间线 Audacity 的时间表示例 由于有数百万个时间点 普通的 Javascript 图形库可能无法解决它 我认为 不确定 普通的
  • Dialogflow 中“意图”和“操作”之间的关系是什么?

    我在概念化 Dialogflow 代理中的 意图 和 操作 之间的关系时遇到了一些麻烦 我了解到意图将用户的口头请求映射到我的履行服务的特定功能 并可选择携带参数作为输入变量 这就是意图的定义方式官方文档 https dialogflow
  • 角度类型的BehaviorSubject

    假设我有一个模型用户 我想创建一个 User 类型的BehaviorSubject 如下所示 private userSource new BehaviorSubject
  • 在Powershell中,如何等待并行作业完成后再继续?

    基于如何并行执行PowerShell函数多次 https stackoverflow com questions 12766174 how to execute a powershell function several times in
  • Pandas 按 Zscore 过滤每组异常

    我有一个数据框 其中的 组 列可以有 50 个不同的值 还有一个数字 值 列 一个例子可以是 pd DataFrame group a b c a a b a c c value 2 123 4 2 3 2 5 127 128 4 0 00
  • 如何在sparkR中绑定两个数据框列?

    如何在spark 1 4的SparkR中绑定两列dataframe 蒂亚 阿伦 没有办法做到这一点 这是一个关于scala中的spark 1 3 的问题 能够做到这一点的唯一方法是使用某种 row numbering 因为这样您就可以加入
  • Rails 用范围扩展领域,PG 不喜欢它

    我有一个小部件模型 小部件属于 Store 模型 Store 模型属于 Area 模型 Area 模型属于 Company 在公司模型中 我需要找到所有关联的小部件 简单的 class Widget lt ActiveRecord Base