我以前有一个类似于Rails的查询:
MyModel.where(id: ids)
它生成sql查询,如下所示:
SELECT "my_models".* FROM "my_models"
WHERE "my_models"."id" IN (1, 28, 7, 8, 12)
现在我想将其更改为使用ANY
而不是IN
。我创建了这个:
MyModel.where("id = ANY(VALUES(#{ids.join '),('}))"
现在,当我使用空数组时,我得到以下错误:
MyModel Load (53.0ms) SELECT "my_models".* FROM "my_models" WHERE (id = ANY(VALUES()))
ActiveRecord::JDBCError: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
ActiveRecord::StatementInvalid: ActiveRecord::JDBCError: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
Position: 75: SELECT "social_messages".* FROM "social_messages" WHERE (id = ANY(VALUES()))
from arjdbc/jdbc/RubyJdbcConnection.java:838:in `execute_query'
IN
表达式有两种变体:
表达式IN(子查询)
表达式IN(值[,...])
同样,具有ANY
构造的两个变体:
子查询适用于这两种技术,但对于每种技术的第二种形式,中的需要一个值列表(如标准SQL中定义的那样),而
=任何
都需要一个数组。
ANY
是一个更新的、更通用的添加,它可以与任何返回布尔值的二进制运算符结合使用。IN
可归结为ANY
的特例。事实上,它的第二种形式是在内部重写的:
中的
被重写为
=任何
不在
中的
被重写为
检查EXPLAIN(解释)输出中的任何查询,以便自己查看。这证明了两件事:
IN
永远不会比=ANY
更快。
=ANY
不会更快。
选择应该由更容易提供的内容决定:值列表或数组(可能是数组文字-单个值)。
如果您要传递的ID无论如何都来自DB内部,那么直接选择它们(子查询)或使用连接将源表集成到查询中(如@mu注释)会更加有效。
=任何中则不会。更多信息:要从客户端传递一长串值并获得最佳性能,请使用数组、
或unnest()
和join,或者使用值将其作为表表达式提供(如@PinnyM注释)。但请注意,联接会在提供的数组/集中保留可能的重复项,而在
在存在空值的情况下,不在
通常是错误的选择,而不存在
则是正确的(而且速度更快):
对于Postgres接受的数组表达式:
数组[1,2,3]
要避免无效的类型转换,可以显式转换:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
相关:
或者,您可以创建一个Postgres函数,该函数使用一个可变参数,该参数接受各个参数并从中形成一个数组:
假设id为整数:
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
但我只是在尝试Ruby@mu在相关回答中提供了详细说明:
问题内容: 在JPA中,查询为: 如何在JPA中将类别设置为任何类别?因此,如果传递了null类别,我将简单地忽略category参数,选择所有产品。 问题答案: 如何在JPA中将类别设置为任何类别?因此,如果传递了null类别,我将简单地忽略category参数,选择所有产品。 您必须在此处动态构建查询。使用HQL(这是一个简化的示例): 但是,实际上,我的建议是在此处使用Criteria AP
问题内容: 我正在尝试搜索文本和备注的多列,以查找某些我不想看到的特定短语和黑名单短语。 假设下表 前任。我想找到所有提到(在任何领域中)“苹果”但黑名单中的“苹果酱”的故事。 如何在where子句中使用别名?我找不到有关此主题的任何文档: 1)这种方法可行吗? 2)替代方法是否意味着我将在每次行迭代中执行多个字符串连接? 问题答案: 我不能在where子句中使用别名。 这种方法可行吗? 当然,将
问题内容: 为什么不能在where子句中使用临时列? 例如,此查询: 这将显示两列,一列称为,另一列称为。是即时创建的,始终为1或0,具体取决于是否有50个或该品牌的产品。 这一切对我来说都是有意义的,除了我不能仅在以下查询中选择时: 这给了我这个错误: 问题答案: 使用来代替: 被评估 前 的。被评估之后。
问题内容: 在WHERE子句中有使用SELECT语句描述的名称吗?这是好/不好的做法吗? 这会是更好的选择吗? 它远没有那么优雅,但是运行起来比以前的版本要快。我不喜欢它,因为它在GUI中没有非常清晰地显示(并且SQL初学者需要理解它)。我可以将其分为两个独立的查询,但是随后事情变得混乱了…… 注意:我不仅需要日期和分数(例如姓名) 问题答案: 称为相关子查询。它有它的用途。
问题内容: 我想在Derby数据库中模拟以下类型的查询(即Microsoft SQL Server语法)的效果。目标是返回表中存储在“ someColumn”中的日期少于7天的所有记录。这是我希望实现的Microsoft SQL语法… 我已经能够确定在Derby中它将涉及使用timestampdiff函数。但是我不知道Derby中WHERE子句中函数用法的语法,因此我找不到任何示例。我发现了很多在
问题内容: 假设我有这张桌子 我想返回第一行,其中所有先前现金的总和大于某个值: 因此,例如,如果我要返回第一行,其中所有先前现金的总和都大于500,则应返回到第3行 如何使用mysql语句执行此操作? 使用 不起作用 问题答案: 您只能在HAVING子句中使用聚合进行比较: 该子句要求您定义GROUP BY子句。 要获得第一行,其中所有先前现金的总和都大于某个值,请使用: 由于聚合函数发生在子查