SQL запрос на подсчет количества проверок в месяц - PullRequest
0 голосов
/ 20 апреля 2020

Короче говоря, я работаю над базой данных, используя PostgreSQL, которая управляет проверками yelp. У checkintable есть атрибуты business_id (строка), дата (строка в форме гггг-мм-дд) и время (строка в форме 00:00:00).

Что мне просто нужно сделать, так это business_id, мне нужно вернуть список общего количества проверок, основываясь только на значении мм (месяц).

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

Любая помощь будет принята с благодарностью. Я уже рассматривал группировку по предложениям, но не знал, как учитывать «% mm%».

Ответы [ 2 ]

3 голосов
/ 20 апреля 2020

Повторение Гордона, класс или нет, сохранение даты и времени в виде строк делает вещи сложнее, медленнее и с большей вероятностью сломается. Труднее воспользоваться 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 = ? или оно будет отфильтровывать пустые месяцы после того, как произошло левое соединение. Вместо этого мы должны поместить это как часть левого соединения.

Попробуйте .

3 голосов
/ 20 апреля 2020

Зачем вам хранить дату в виде строки? Это сломанная модель данных. Вам следует исправить данные.

При этом я рекомендую преобразовать дату и усечь ее до первого дня месяца:

select date_trunc('day', datestr::date) as yyyymm, count(*)
from t
group by yyyymm
order by yyyymm;

Если вы не хотите, чтобы они основывались на году , затем используйте extract():

select extract(month from datestr::date) as mm, count(*)
from t
group by mm
order by mm;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...