Как использовать предложение "where" с условием "order" - PullRequest
2 голосов
/ 06 мая 2019

У меня есть модель Trade, в которой есть столбцы traded_at, price, amount.

И для этого есть default_order.

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

Я хочу отфильтровать 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, мне нужно добавить 4 условия в предложении where. Я думаю, что это не эффективно. Есть ли способ использовать условие order для предложения where?

1 Ответ

3 голосов
/ 06 мая 2019

Postgres поддерживает концепцию ROW значений .

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

Но есть заминка : каждое поле вСтрока сравнивается в том же смысле упорядочения.Ваш случай имеет смешанный порядок сортировки (ASC / DESC), который показывает showtopper.Но если 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.

Связано:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...