Повторение Гордона, класс или нет, сохранение даты и времени в виде строк делает вещи сложнее, медленнее и с большей вероятностью сломается. Труднее воспользоваться Postgres мощными математическими функциями даты . Хранение даты и времени отдельно усложняет ситуацию; Вы должны объединить их вместе, чтобы получить полную метку времени, что означает, что она не будет проиндексирована. Определение времени между двумя событиями становится излишне трудным.
Это должен быть один столбец timestamp . Надеюсь, ваш класс представит это в ближайшее время.
Что мне нужно сделать, так это, учитывая business_id, мне нужно вернуть список общего числа проверок, основанный только на значении mm (month) .
Это обманчиво просто. Приведите свои строки к датам, к счастью, они в формате ISO 8601, поэтому переформатирование не требуется. Затем используйте extract
, чтобы извлечь только часть месяца.
select
extract('month' from checkin_date::date) as month,
count(*)
from yelp_checkins
where business_id = ?
group by month
order by month
Но есть загвоздка. Что делать, если в конкретном месяце нет регистрации для бизнеса? Мы не получим запись за этот месяц. Это довольно распространенная проблема.
Если нам нужна строка для каждого месяца, нам нужно сгенерировать таблицу с желаемыми месяцами с generate_series
, а затем оставить соединение с нашей таблицей регистрации. , Левое объединение гарантирует, что все месяцы («левая» таблица) будут там, даже если в объединяющей таблице («правая» таблица) нет соответствующего месяца.
select
months.month,
count(business_id)
from generate_series(1,12) as months(month)
left join yelp_checkins
on months.month = extract('month' from checkin_date::date)
and business_id = ?
group by months.month
order by months.month
Теперь, когда у нас есть таблица месяцев, мы можем сгруппировать по этому. Мы не можем использовать предложение where business_id = ?
или оно будет отфильтровывать пустые месяцы после того, как произошло левое соединение. Вместо этого мы должны поместить это как часть левого соединения.
Попробуйте .