5

Есть запрос такого вида

Сущность.where(calendars: {date: "1.07.2015"}).count

Мне возвращает количество записей с значением "1.07.2015" в поле date. Но мне надо запрашивать именно 7й месяц (или любой другой). Как отфильтровать и поставить условие на date?

Вот код самой миграции

create_table :calendar do |t|           
  t.belongs_to :user, index: true
  t.belongs_to :days_info, index: true
  t.datetime :date
  t.timestamps
end
Nicolas Chabanovsky
  • 51,426
  • 87
  • 267
  • 507
ks_on_v
  • 1,227
  • Вас интересует запрос в БД на 7-ой месяц конкретного (произвольного на уровне приложения) года, или любого? Последнее существенно сложнее. –  Sep 08 '15 at 18:06
  • Планирую задавать один из 12ти месяцев цифрой и получать данные за этот месяц. – ks_on_v Sep 09 '15 at 03:06
  • И год тоже задавать, само число месяца не нужно по сути. – ks_on_v Sep 09 '15 at 03:29

3 Answers3

4

Попробуйте так:

What.where(calendars: {date: '1.07.2015'.to_date...'1.07.2015'.to_date + 1.month}).count
MAXOPKA
  • 2,166
  • 2
    Вот так, только, будет только чуть более универсально и чище: '1.07.2015'.to_date.beginning_of_month..'1.07.2015'.to_date.end_of_month – anoam Sep 08 '15 at 09:52
  • Хм, у меня ноль, хотя значения есть, с моим же запросом на первое число count > 0. – ks_on_v Sep 08 '15 at 09:58
  • @ks_on_v а какой тип данных у поля date? А лучше добавьте миграции в вопрос. – MAXOPKA Sep 08 '15 at 09:59
  • create_table :calendar do |t|
    t.belongs_to :user, index: true t.belongs_to :days_info, index: true t.datetime :date t.timestamps end
    – ks_on_v Sep 08 '15 at 10:26
  • @ks_on_v а попробуйте для обоих запросов, вместо .count написать .to_sql, и посмотреть, какие запросы генерируются. – MAXOPKA Sep 08 '15 at 11:07
  • SELECT "days_infos".* FROM "days_infos" INNER JOIN "calendars" ON "days_infos"."id" = "calendars"."days_info_id" WHERE "calendars"."user_id" = ? AND ("calendars"."date" BETWEEN '2015-07-01' AND '2015-07-31') Вроде то. У меня такая база, https://neepic.com/znoEJNWl , у calendar еще date поле есть. – ks_on_v Sep 08 '15 at 11:16
  • Надо ли index в бд добавлять? – ks_on_v Sep 10 '15 at 05:55
  • @ks_on_v желательно внешние ключи в таблицах делать индексами. Но на логику работы запросов это никак не влияет. Только на скорость выборки. – MAXOPKA Sep 10 '15 at 06:22
  • А зачем вообще индексы нужны? – ks_on_v Sep 10 '15 at 06:29
  • @ks_on_v чтобы выборка быстрее выполнялась. – MAXOPKA Sep 10 '15 at 06:33
  • Таким образом я могу все поля индексами сделать и не париться... – ks_on_v Sep 10 '15 at 06:38
  • @ks_on_v вам сюда https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D0%B4%D0%B5%D0%BA%D1%81_(%D0%B1%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85) – MAXOPKA Sep 10 '15 at 06:47
  • Я понял, запрос почему-то считает, что ячейка типа char. Потому что если запрашивать '1.07.2015', то значения приходят, а если '1.07.2015'.to_date то ничего....Как быть? Массив строк для получения значений не вариант отправлять... – ks_on_v Sep 11 '15 at 05:07
  • @ks_on_v если в миграции указано, что t.datetime :date, то всё должно быть нормально. Если, конечно, таблица создавалась по этой миграции. – MAXOPKA Sep 11 '15 at 06:18
  • Да вроде все правильно, но интервалы не работают. А запросы одинаковые, только концом отличаются (одна дата или интервал) – ks_on_v Sep 11 '15 at 06:21
  • Вот два запроса, первый не работает, второй работает:
    1. SELECT "days_infos".* FROM "days_infos" INNER JOIN "calendars" ON "days_infos"."id" = "calendars"."days_info_id" WHERE "calendars"."user_id" = ? AND ("calendars"."date" BETWEEN '2015-07-01' AND '2015-07-31')
    2. SELECT "days_infos".* FROM "days_infos" INNER JOIN "calendars" ON "days_infos"."id" = "calendars"."days_info_id" WHERE "calendars"."user_id" = ? AND "calendars"."date" = '1.07.2015'
    – ks_on_v Sep 11 '15 at 06:29
1
date = '1.07.2015'
daterange = date.to_datetime.beginning_of_month..date.to_datetime.end_of_month
Item.includes(:calendars).where(calendars: {date: daterange}).count
kolas
  • 121
  • Запрос вроде правильный: SELECT "days_infos".* FROM "days_infos" INNER JOIN "calendars" ON "days_infos"."id" = "calendars"."days_info_id" WHERE "calendars"."user_id" = ? AND ("calendars"."date" BETWEEN '2015-07-01 00:00:00.000000' AND '2015-07-31 23:59:59.000000'). Но count все равно 0. – ks_on_v Sep 09 '15 at 10:50
  • Может по коду я сделал не так, что-то? Хотя запрос current_user.days_info.where(calendars: {date: '1.07.2015'}).count работает, значит зависимости правильно указаны.... – ks_on_v Sep 09 '15 at 10:58
  • @ks_on_v Что за СУБД? У вас же поле date типа datetime, если просто строку даешь как она находит запись? – kolas Sep 10 '15 at 05:54
  • SQLite. В смысле просто строку даешь? – ks_on_v Sep 10 '15 at 05:56
1

В общем удалил поле date:datetime и создал два поля month:integer и year:integer. Да избыточности много....

ks_on_v
  • 1,227