sql – 如何在带有Rails的WHERE子句中使用ANY而不是IN?
我曾经有过如下查询:
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 '),('}))" 现在,当我使用空数组ids = []时,我得到以下错误: 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表达式有两种变体:> 同样,具有ANY构造的两个变体: > 子查询适用于任何一种技术,但对于每种技术的第二种形式,IN需要一个值列表(如标准SQL中所定义),而= ANY需要一个数组. 哪个用? ANY是一个更加通用的新增功能,可以与任何返回布尔值的二元运算符组合使用. IN归结为任何特殊情况.事实上,它的第二种形式在内部被重写: IN用= ANY重写 检查EXPLAIN输出以查找任何查询以便自己查看.这证明了两件事: > IN永远不会超过= ANY. 选择应该由更容易提供的内容决定:值列表或数组(可能作为数组文字 – 单个值). 如果您要传递的ID仍然来自数据库中,则直接选择它们(子查询)或使用JOIN将源表集成到查询中(如@mu commented)则更有效. 要从客户端传递一长串值并获得最佳性能,请使用数组,unexst()和join,或使用VALUES(如@PinnyM commented)将其作为表表达式提供.更多: > Optimizing a Postgres query with a large IN 在存在NULL值的情况下,NOT IN通常是错误的选择,NOT EXISTS是正确的(也更快): > Select rows which are not present in other table 语法= ANY 对于数组表达式,Postgres接受: >一个array constructor(数组由Postgres一侧的值列表构成)形式:ARRAY [1,2,3] 要避免无效的类型转换,您可以显式转换: ARRAY[1,3]::numeric[] '{1,3}'::bigint[] 有关: > PostgreSQL: Issue with passing array to procedure 或者你可以使用VARIADIC参数创建一个Postgres函数,该参数接受各个参数并从中形成一个数组: > Passing multiple values in single parameter 如何从Ruby传递数组? 假设id为整数: MyModel.where('id = ANY(ARRAY[?]::int[])',ids.map { |i| i}) 但我只是涉足Ruby. @mu提供了相关答案的详细说明: > Sending array of values to a sql query in ruby? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |