SQL客户数据库查询转Rails等价ActiveRecord查询技术问询
补全等价于目标SQL的Rails查询语句并验证等价性
原问题引用
将现有可成功查询客户数据库的SQL语句:
SELECT "customers".* FROM "customers" WHERE ((("customers"."first_name" IN ('John', 'Doe') OR "customers"."last_name" IN ('John', 'Doe')) OR "customers"."email" IN ('John', 'Doe')) OR "customers"."main_phone" IN ('John', 'Doe'))已编写部分等价Rails查询代码:
array = ["John","Doe","111-111-1111"] Customer.where(first_name: array).or(customers.where(last_name: array)).or(customers.where(email: array)).or(cus...请补全该Rails查询语句,并确认其与原SQL查询的等价性。
补全后的Rails查询代码
首先要注意,你代码里的customers应该替换为模型类Customer(除非你提前定义了同名变量,否则直接用模型类构建查询是Rails的标准写法)。补全后的完整代码如下:
array = ["John","Doe","111-111-1111"] Customer.where(first_name: array) .or(Customer.where(last_name: array)) .or(Customer.where(email: array)) .or(Customer.where(main_phone: array))
等价性验证
这段Rails代码和你提供的原SQL在逻辑结构上完全等价,具体对应关系如下:
- Rails的
where(column: array)语法会直接转换为SQL的column IN ('value1', 'value2', ...)条件,和原SQL的IN子句完全匹配。 - 链式调用的
.or方法会将多个where条件用OR连接起来,原SQL里的多层括号只是优先级的冗余写法(因为OR是左结合运算符,多层嵌套和连续OR的逻辑完全一致),所以最终生成的SQL条件逻辑和原SQL完全相同。
如果你想直观验证生成的SQL,可以在Rails控制台里调用.to_sql方法,比如:
# 执行上述查询后调用to_sql puts Customer.where(first_name: array).or(Customer.where(last_name: array)).or(Customer.where(email: array)).or(Customer.where(main_phone: array)).to_sql
会输出类似这样的SQL(和原SQL结构一致,只是IN的取值包含了你定义的111-111-1111):
SELECT "customers".* FROM "customers" WHERE ("customers"."first_name" IN ('John', 'Doe', '111-111-1111') OR "customers"."last_name" IN ('John', 'Doe', '111-111-1111') OR "customers"."email" IN ('John', 'Doe', '111-111-1111') OR "customers"."main_phone" IN ('John', 'Doe', '111-111-1111'))
如果需要完全匹配原SQL的IN取值(仅John和Doe),只需要把array改成["John", "Doe"]即可,此时生成的SQL就和你提供的原SQL完全一致了。
内容的提问来源于stack exchange,提问作者Cannon Moyer
相关产品推荐
相关产品推荐

