Мне нужно найти ближайшую дату в приложении рельсы - PullRequest
2 голосов
/ 26 октября 2010

Мне нужно найти ближайшую дату к данной дате, используя рельсы с именем scope.

С MySql я мог бы использовать DATEDIFF, но я хочу сохранить агностицизм базы данных, следующее не работает с Sqlite:

named_scope :closest_to, lambda { |*args|
  date  = args.first
  count = args[1] || 1
  {:limit => count, :order => "ABS(DATEDIFF(hour, date_field, #{date.to_formatted_s :db}))"}
}

Ответы [ 4 ]

3 голосов
/ 17 мая 2013

Если вы используете Postgres, вы должны использовать EXTRACT(EPOCH FROM ()) для преобразования интервала в секунды, поскольку ABS принимает только числа в качестве аргументов.

scope :order_by_closest_to, lambda { |date|
  {:order => %{ABS(EXTRACT(EPOCH FROM ('#{date.to_formatted_s(:db)}'::timestamp - some_timestamp_column))) asc} }
}

Я не думаю, что есть какой-либо независимый от базы данных способ выполнить этот запрос, так как функции и приведение типов различаются для mysql, postgres и sqlite.

3 голосов
/ 29 октября 2010

Решено это так:

named_scope :order_by_closest_to, lambda { |date|
  {:order => %{ABS(strftime('%s', "#{date.to_formatted_s(:db)}") - strftime('%s', value)) asc} }
}

Таким образом, я могу смешивать с другими именованными областями и ограничивать количество результатов, чтобы он не перебирал все записи.

2 голосов
/ 26 октября 2010

Один из вариантов - использовать что-то вроде:

:limit => count, :select => "*, abs(date('#{date.to_formatted_s :db}') - date('#{date_field}')) as date_diff", :order => "date_diff"

Может быть немного интенсивно работать с базой данных, поскольку он должен вычислять поле date_diff из всех записей.

0 голосов
/ 15 февраля 2011

В SQL вышеупомянутое обычно решается с помощью чего-то вроде:

SELECT *
FROM my_table
WHERE start_date = ( SELECT MAX(start_date) FROM my_table WHERE start_date <= '2011-02-18' )

Это может быть сделано для работы со всеми базами данных, которые поддерживают подзапросы (SQLite не работает).Большой обзор SQL "Point in Time" здесь: http://www.orafaq.com/node/1834

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