如何在“ order”条件下使用“ where”子句

时间:2019-05-06 16:43:11

标签: sql ruby-on-rails postgresql activerecord

我有一个模型Trade,其中有列traded_atpriceamount

有一个default_order这样的东西。

scope :default_order, -> {
  order(traded_at: :desc, price: :asc, amount: :desc)
}

我想使用此order子句过滤trades

这是我的不含订单条款的代码。

scope :newer_than, ->(trade) {
  where(<<-SQL)
    traded_at > '#{trade.traded_at.to_s(:db)}' OR
    (traded_at = '#{trade.traded_at.to_s(:db)}' AND price < #{trade.price}) OR
    (traded_at = '#{trade.traded_at.to_s(:db)}' AND price = #{trade.price} AND amount > #{trade.amount})
  SQL
}

当我为order子句添加一个条件时,我需要在where子句中添加4个条件。 我认为效率不高。是否可以对order子句使用where条件?

1 个答案:

答案 0 :(得分:3)

Postgres支持ROW values的概念。

SELECT * FROM tbl WHERE (a, b, c) > (1, 2, 3)  -- not for you!

但是有一个障碍:以相同的顺序对行中的每个字段进行比较。您的案件具有混合排序顺序(ASC / DESC),这是一个大热门。但是,如果price是数字数据类型(似乎是一个安全的下注)-定义了取反器,则有一种解决方法:

... WHERE (a, -b, c) > (1, -2, 3)  -- for you

所以:

where(<<-SQL)
    (traded_at, -price, amount)
  > ('#{trade.traded_at.to_s(:db)}', #{trade.price} * -1 , #{trade.amount})
  SQL

或通过trade.price并立即取反并丢下* -1

甚至可以通过多列表达式索引来支持!

注意:这与 NULL值都不能正常工作,因为这些值永远不会在您的WHERE子句中起作用。

相关: