2016-06-02 7 views
1

Я пытаюсь найти запись и заказать ее по шкафу день в зависимости от текущего дня.Ближайший день в массиве sql

Позвольте мне проиллюстрировать пример.

Скажите, что Джон хочет узнать, когда ему нужно научить следующего. Джон учит следующие дни (дни конвертируются в числа, где 0 = воскресенье, 1 = понедельник ...) [1,2]. Текущий день - пятница (5), поэтому результат должен быть .

Другой пример:

Карен хочет, чтобы выяснить, когда она должна учить дальше. Карен преподает следующие дни: [0,2,3]. Текущий день - четверг (4), поэтому результат должен быть .

Текущий запрос:

TeamOverview.where(coach: current_user.id).order(:day = [next closets day missing here]) 

Модель:

t.string :name 
    t.integer :coach 
    t.int  :day 

Возможные записи в модели:

id: 1, name: John, day: 1 
id: 2, name: John, day: 2 
id: 3, name: Karen, day: 0 
id: 4, name: Karen, day: 2 
id: 5, name: Karen, day: 3 
+0

действительно ли дни повторяются как [0,2,4,0,1]? – chaitanya

+0

@chaitanya нет, вы можете рассматривать его как набор, где каждый случай появляется только один раз –

ответ

0

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

К сожалению, оператор % (по модулю с PostgreSQL сохраняет знак для отрицательных значений Таким образом, вы не можете использовать day - current_day

Но упорядочение по следующему выражению сортирует строки в соответствии с вашим intened логики:..

(7 + day - current_day) % 7 

day ГДЕ это день образуют модельный ряд и current_day является значением для текущего дня для использования с расчетом.

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

CASE WHEN day < current_day THEN 7 + day - current_day ELSE day - current_day END 
+0

Я не уверен, как вы включили бы это в инструкцию заказа? –

1

Чтобы избежать комплексного решения я бы лучше выбрать все рабочие дни и сделать работу в рубин. Максимальное количество результатов запроса - 7 - это должно быть хорошо. Кроме того, изменения высоки, что у вас уже есть такой запрос (возможно, в TeamOverview), вы можете повторно использовать это, а при втором вызове он также может появиться из кеша запросов.

working_days = TeamOverview.where(coach: current_user.id).pluck(:day) 
working_days.find { |day_num| day_num > today_num } || working_days.first 
-1

После код будет найти следующий предстоящий день, если вам нужно дней затем удалить .first рассуждение

next_day = TeamOverview.where("day > ? and coach_id = ?", current_day, current_user.id).order("day").first 
+0

Это дает мне ошибку: PG :: UndefinedFunction: ERROR: operator не существует: character variableing> integer –

+0

Это не соответствует действительности. 'next_day' может быть НИЖНИЕ, чем' current_day'. Именно это делает проблематичным вопрос в первую очередь. –

0
(res =TeamOverview.where(coach: current_user.id).order("day").find(:first, :conditions => [ "(day > ?)",current_day])) ? res : TeamOverview.where(coach: current_user.id).order("day").find(:first, :conditions => [ "(day < ?)",current_day]) 

Это даст вам желаемый результат

+0

Это недопустимый синтаксис. Вы можете * вместо этого сделать что-то вроде: 'res = TeamOverview.where (coach: current_user.id) .order (" day "). Find (: first,: conditions => [" (day>?) ", Current_day])) || TeamOverview.where (coach: current_user.id) .order («день»). Сначала, хотя это не идеальное решение, так как вы не возвращаете полный порядок предстоящих дней; вместо этого вы выбираете * следующий * день. (Которое может быть достаточно, для потребностей OP, я не уверен.) –

0

Вы можете добиться этого в чистом SQL с двухчастным заказом:

Простая реализация в ActiveRecord для этого:

TeamOverview 
    .where(coach: current_user.id) 
    .order("day < #{current_day}") 
    .order(:day) 

Или, если вы предпочитаете:

TeamOverview 
    .where(coach: current_user.id) 
    .order("day < #{current_day}, day") 

Предупреждение: Приведенный выше код является потенциально уязвимым для SQL инъекций. Убедитесь, что вы доверяете источнику current_day и дезинфицируете (в этом случае, возможно, просто позвоните to_i), если это необходимо.

К сожалению, looking at the rails source code (как текущей 4.2.6 версии на момент публикации), это выглядит, как если бы синтаксис ? не поддерживается методом order ActiveRecord - то есть следующее недействителен: TeamOverview.order("day < ?", current_day). Возможно, это будет хорошим дополнением к библиотеке.

Смежные вопросы