ruby-on-rails - 使用 PostgreSQL OVERLAPS 方法的 Arel 表
问题描述
让我先承认有几种不同的方法可以完成重叠,但关于这个问题,我特别想弄清楚如何使用实际的PostgreSQL OVERLAPS
方法Arel
。为此,这个问题更多地与更好地理解 Arel 有关,而不是实现某些版本的重叠功能。
我在用着Rails 5.1
这是我试图在 Arel 中复制的 SQL 语句:
SELECT DISTINCT
venues.id
FROM
venues
LEFT OUTER JOIN
reservations
ON
venues.id = reservations.venue_id
WHERE (
(reservations.venue_id IS NULL)
OR NOT (
(reservations.start, reservations.end)
OVERLAPS
(DATE '2018-09-02', DATE '2018-09-03')
)
)
我目前有以下确实会生成上述内容:
Venue.arel_table.project(
Venue.arel_table[:id]
).from(
Venue.arel_table
).join(
Reservation.arel_table, Arel::Nodes::OuterJoin
).on(
Venue.arel_table[:id].eq(Reservation.arel_table[:venue_id])
).where(
Arel::Nodes::Grouping.new(
Reservation.arel_table[:venue_id].eq(nil)
).or(
Arel.sql("NOT ((reservations.start, reservations.end) OVERLAPS (DATE '2018-09-02', DATE '2018-09-03'))")
)
)
但是,我觉得可能有更好的方法来做到这一点;我一直在尝试实现Arel::Nodes::NamedFunction
,OVERLAPS
但是,当我用Arel.sql
以下语句替换上面的语句时,它没有正确执行 SQL:
Arel::Nodes::NamedFunction.new(
'OVERLAPS',
[
Arel::Nodes::SqlLiteral.new('(reservations.start, reservations.end)'),
Arel::Nodes::SqlLiteral.new("(DATE '2018-09-02', DATE '2018-09-03')")
]
)
结果是
...OVERLAPS ((reservations.start, reservations.end), (DATE '2018-09-02', DATE '2018-09-03'))
OVERLAPS
实施with的正确方法是什么Arel
?
解决方案
由于OVERLAPS
是 SQL 运算符,我相信以下表达式应该有效:
Arel::Nodes::InfixOperation.new(
'OVERLAPS',
Arel::Nodes::SqlLiteral.new('(reservations.start, reservations.end)'),
Arel::Nodes::SqlLiteral.new("(DATE '2018-09-02', DATE '2018-09-03')"
)
推荐阅读
- java - 是否可以设置 JScrollPane 或 JScrollBar 的箭头样式?
- c++ - 程序必须将奇数索引元素放在一个新向量 C 中,将偶数索引元素放在另一个向量 T 中
- rasa-nlu - 为什么我不能在 RASA 中加载一些库
- javascript - 在 vue/vuex 中保存或取消编辑
- sql - 如果它们有多个元组,则选择具有两列相同但另一列不同的行
- macos - 安装 Homebrew 时出错:dyld:未加载库:@rpath/libssl.1.0.0.dylib
- ruby - 识别包含列表中每个字符的字符串
- php - Wordpress/WooCommerce 功能仅适用于特定产品类别
- nginx - Kubernetes 服务的 Nginx 路由
- r - R:如何设置Lambert投影的地图范围?