Получение количества строк и возврат 0 при отсутствии строк

Я написал запрос, чтобы узнать, сколько регистраций на веб-сайтах у меня было каждый день:

SELECT created, COUNT(id)
FROM signups
GROUP BY created
ORDER BY created desc

Однако при этом извлекаются строки только для тех дней, когда люди действительно зарегистрировались. Если никто не зарегистрировался в течение дня, я хотел бы вернуть 0 за этот день. Есть ли способ сделать это с помощью SQL или мне придется анализировать результаты с помощью PHP?


person James Dawson    schedule 23.07.2013    source источник
comment
если никто не зарегистрируется, для этого дня не будет созданной записи, поэтому он не будет отображать счет за этот день.   -  person DevZer0    schedule 23.07.2013
comment
Как сказал DevZero, MySQL не может вывести информацию, которой у него нет. Вам нужно будет проанализировать его с помощью PHP, чтобы вставить пропущенные дни со счетом 0.   -  person AgmLauncher    schedule 23.07.2013
comment
@ DevZer0, да, в этом проблема. Мне было интересно, есть ли способ зациклить и вставить пропущенные даты со значением 0. Похоже, что нет.   -  person James Dawson    schedule 23.07.2013
comment
Вы забыли предоставить определение таблицы с типами данных ваших столбцов и вашей версией Postgres.   -  person Erwin Brandstetter    schedule 23.07.2013
comment
@AgmLauncher Хотя это может быть невозможно в MySQL, это возможно в Postgres.   -  person Ihor Romanchenko    schedule 23.07.2013


Ответы (4)


Предполагая, что created относится к типу date из-за отсутствия информации.

Postgres предоставляет замечательную возможность generate_series() для сделать это легко:

SELECT d.created, COUNT(s.id) AS ct
FROM  (
   SELECT generate_series(min(created)
                        , max(created), interval '1 day')::date AS created
   FROM   signups
   ) d
LEFT   JOIN signups s USING (created)
GROUP  BY 1
ORDER  BY 1 DESC;

Это автоматически извлекает минимальный и максимальный день из вашей таблицы и предоставляет одну строку в день между ними.

person Erwin Brandstetter    schedule 23.07.2013

Вы можете использовать функцию NULLIF:

   SELECT created, NULLIF(COUNT(id), 0)
     FROM signups
 GROUP BY created
 ORDER BY created desc

Документация: http://www.postgresql.org/docs/8.1/static/functions-conditional.html

person Bora    schedule 23.07.2013
comment
Это не работает, потому что если в signups нет записей за этот день, ничего не возвращается. - person James Dawson; 23.07.2013
comment
Вы пробовали функцию num rows после результата запроса? $результат = pg_query(ЗАПРОС); pg_num_rows ($ результат); Документ - person Bora; 23.07.2013

Вам нужно использовать календарную таблицу с рядом дат и присоединиться к ней.

select cal.created,coalesce(total) as total from calender_table as cal left join
(
SELECT created, COUNT(id) as total
FROM signups
GROUP BY created
) as source on cal.created=source.created
ORDER BY cal.created desc
person Madhivanan    schedule 23.07.2013

Вы должны создать таблицу календаря в своей базе данных (или сгенерировать ее в запросе) и соединить ее со своей, тогда вы получите 0 за пустые дни.

SELECT calendar.c_date, COUNT(signups.id)
FROM calendar
left join signups on calendar.c_date=signups.created

GROUP BY c_date
ORDER BY c_date desc

Вот способ сделать календарную дату в PostgreSQL

person valex    schedule 23.07.2013