[英]How to use “where” clause with “order” condition
I have a model Trade
that has columns traded_at
, price
, amount
. 我有一个模型Trade
,其中包含traded_at
, price
, amount
列。
And there is a default_order
for it like this. 并且有一个default_order
这样的。
scope :default_order, -> {
order(traded_at: :desc, price: :asc, amount: :desc)
}
I want to filter the trades
by using this order clause. 我想通过使用此订单子句来过滤trades
。
This is my code for it without order clause. 这是我的没有订单条款的代码。
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
}
When I add one more condition for order
clause, I need to add 4 condition in where
clause. 当我为order
子句添加一个条件时,我需要在where
子句中添加4个条件。 I think it's not efficient. 我认为效率不高。 Is there way to use order
condition for where
clause? 是否可以对where
子句使用order
条件?
Postgres supports the concept of ROW
values . Postgres支持ROW
值的概念。
SELECT * FROM tbl WHERE (a, b, c) > (1, 2, 3) -- not for you!
But there is a hitch : every field in the row is compared in the same sense of ordering. 但是有一个障碍 :以相同的顺序对行中的每个字段进行比较。 Your case has mixed sort order ( ASC
/ DESC
), which is a showstopper. 您的案件具有混合排序顺序( ASC
/ DESC
),这是一个排头兵。 But if price
is a numeric data type (seems like a safe bet) - which has a negator defined, there is a workaround: 但是,如果price
是数字数据类型(似乎是一个安全的下注)-定义了否定符 ,则有一种解决方法:
... WHERE (a, -b, c) > (1, -2, 3) -- for you
So: 所以:
where(<<-SQL)
(traded_at, -price, amount)
> ('#{trade.traded_at.to_s(:db)}', #{trade.price} * -1 , #{trade.amount})
SQL
Or pass trade.price
readily negated and drop * -1
. 或通过trade.price
轻松否定并下跌* -1
。
Can even be supported with a multicolumn expression index! 甚至可以通过多列表达式索引来支持!
Note: None of this works properly with NULL values since those never qualify in your WHERE
clause. 注意:这些都不能与NULL值一起正常使用,因为NULL值永远不会在您的WHERE
子句中限定。
Related: 有关:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.