【发布时间】:2023-04-09 03:28:01
【问题描述】:
我有以下“距离”表:
╔════╦════════════╦════════════╦═════════════════╦═════════════════╦══════════╗
║ id ║ origin_lat ║ origin_lng ║ destination_lat ║ destination_lng ║ distance ║
╠════╬════════════╬════════════╬═════════════════╬═════════════════╬══════════╣
║ 1 ║ 1.234567 ║ 2.345678 ║ 3.456789 ║ 4.567890 ║ 10 ║
║ 2 ║ 5.678901 ║ 6.789012 ║ 7.890123 ║ 8.901234 ║ 20 ║
╚════╩════════════╩════════════╩═════════════════╩═════════════════╩══════════╝
问题是,如果需要,如何使用 ActiveRecord 和 Arel 创建以下 SQL 查询(PostgreSQL 支持):
SELECT *
FROM distances
WHERE
(origin_lat, origin_lng) IN ((1.234567, 2.345678), (5.678901, 6.789012))
AND
(destination_lat, destination_lng) IN ((3.456789, 4.567890), (7.890123, 8.901234));
我试过了,但它不起作用:
Distance.where('(origin_lat, origin_lng) IN (?) AND (destination_lat, destination_lng) IN (?)', [[1.234567, 2.345678], [5.678901, 6.789012]], [[3.456789, 4.567890], [7.890123, 8.901234]])
它会生成这个:
SELECT "distances".* FROM "distances" WHERE ((origin_lat, origin_lng) IN ('---
- 1.234567
- 2.345678
','---
- 5.678901
- 6.789012
') AND (destination_lat, destination_lng) IN ('---
- 3.456789
- 4.56789
','---
- 7.890123
- 8.901234
'))
并提出PG::FeatureNotSupported: ERROR: input of anonymous composite types is not implemented
参数的数量是可变的,所以我不能像这样硬编码查询:
Distance.where('(origin_lat, origin_lng) IN ((?,?),(?,?)) AND (destination_lat, destination_lng) IN ((?,?),(?,?))', 1.234567, 2.345678, 5.678901, 6.789012, 3.456789, 4.567890, 7.890123, 8.901234)
我需要使用纯 SQL 吗? :/
【问题讨论】:
-
raw sql 是有效查询吗?其实我以前从来没见过。
-
@ArupRakshit 至少在我测试的地方(MySQL 和 PostgreSQL),它是,并且完全符合我的需要。
-
@ArupRakshit 我认为它甚至是标准 SQl,请参阅:stackoverflow.com/questions/6298139/… 和 stackoverflow.com/questions/6672665/…
标签: sql ruby-on-rails ruby postgresql activerecord