【问题标题】:Arel Table with PostgreSQL OVERLAPS method使用 PostgreSQL OVERLAPS 方法的 Arel 表
【发布时间】:2018-09-14 19:40:07
【问题描述】:

首先让我承认有几种不同的方法可以实现重叠,但关于这个问题,我特别想弄清楚如何将实际的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'))")
  )
)

但是,我觉得可能有更好的方法来做到这一点;我一直在尝试为OVERLAPS 实现Arel::Nodes::NamedFunction,但是,当我将上面的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'))

Arel 实现OVERLAPS 的正确方法是什么?

【问题讨论】:

    标签: ruby-on-rails postgresql arel


    【解决方案1】:

    由于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')"
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-26
      • 2020-10-20
      • 1970-01-01
      • 2021-02-16
      • 2018-02-27
      • 1970-01-01
      相关资源
      最近更新 更多