微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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表达式有两种变体:

> expression IN (subquery)
> expression IN (value [,...])

同样,具有ANY构造的两个变体:

> expression operator ANY (subquery)
> expression operator ANY (array expression)

查询适用于任何一种技术,但对于每种技术的第二种形式,IN需要一个值列表(如标准sql中所定义),而= ANY需要一个数组.

哪个用?

ANY是一个更加通用的新增功能,可以与任何返回布尔值的二元运算符组合使用. IN归结为任何特殊情况.事实上,它的第二种形式在内部被重写:

IN用= ANY重写
NOT IN用<>重写所有

检查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]
>或“{1,3}”形式的array literal.

要避免无效的类型转换,您可以显式转换:

ARRAY[1,3]::numeric[]
'{1,3}'::bigint[]

有关:

> PostgreSQL: Issue with passing array to procedure
> How to pass custom type array to Postgres function

或者你可以使用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?

原文地址:https://www.jb51.cc/mssql/78227.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐