Как вставить дополнительные значения между GROUP BY - PullRequest
1 голос
/ 16 сентября 2009

В настоящее время я делаю ежемесячный отчет, используя MySQL. У меня есть таблица с именем «ежемесячно», которая выглядит примерно так:

  id |         date        | amount

  10 | 2009-12-01 22:10:08 | 7 
  9  | 2009-11-01 22:10:08 | 78 
  8  | 2009-10-01 23:10:08 | 5 
  7  | 2009-07-01 21:10:08 | 54 
  6  | 2009-03-01 04:10:08 | 3 
  5  | 2009-02-01 09:10:08 | 456 
  4  | 2009-02-01 14:10:08 | 4 
  3  | 2009-01-01 20:10:08 | 20 
  2  | 2009-01-01 13:10:15 | 10 
  1  | 2008-12-01 10:10:10 | 5 

Затем, когда я делаю ежемесячный отчет (который основан на ежемесячном отчете за год), я получаю что-то вроде этого.

год / месяц | всего

2008-12   | 5 
2009-01   | 30 
2009-02   | 460 
2009-03   | 3 
2009-07   | 54 
2009-10   | 5 
2009-11   | 78 
2009-12   | 7 

Я использовал этот запрос для достижения результата:

ВЫБРАТЬ подстроку (дата, 1, 7) AS год / месяц, сумма (сумма) AS всего ОТ monthly Подстрока GROUP BY (дата, 1, 7)

Но мне нужно что-то вроде этого:

год / месяц | всего

2008-01   | 0 
2008-02   | 0 
2008-03   | 0 
2008-04   | 0 
2008-05   | 0 
2008-06   | 0 
2008-07   | 0 
2008-08   | 0 
2008-09   | 0
2008-10   | 0 
2008-11   | 0 
2008-12   | 5 
2009-01   | 30 
2009-02   | 460 
2009-03   | 3 
2009-05   | 0
2009-06   | 0
2009-07   | 54 
2009-08   | 0
2009-09   | 0
2009-10   | 5 
2009-11   | 78 
2009-12   | 7 

Нечто, отображающее нули за месяц, которое не имеет никакого значения. Возможно ли это сделать в запросе MySQL?

Ответы [ 2 ]

4 голосов
/ 16 сентября 2009

Вы должны сгенерировать фиктивный источник строк и LEFT JOIN с ним:

SELECT  *
FROM    (
        SELECT  1 AS month
        UNION ALL
        SELECT  2
        … 
        UNION ALL
        SELECT  12 
        ) months
CROSS JOIN
        (
        SELECT  2008 AS year
        UNION ALL
        SELECT  2009 AS year
        ) years
LEFT JOIN
        mydata m
ON      m.date >= CONCAT_WS('.', year, month, 1)
        AND m.date < CONCAT_WS('.', year, month, 1) + INTERVAL 1 MONTH
GROUP BY
        year, month

Вы можете создавать их как таблицы на диске, а не генерировать их каждый раз.

MySQL - единственная система из четырех основных, которая позволяет легко генерировать произвольные наборы результатов.

Oracle, SQL Server и PostgreSQL имеют такие значения (CONNECT BY, рекурсивные CTE и generate_series соответственно)

0 голосов
/ 17 сентября 2009

Кассной прав, и я добавлю комментарий о том, как распознавать, когда вам нужно что-то вроде этого:

Вы хотите, чтобы в вашем результате было значение «2008-01», но ни в одной исходной таблице нет даты в январе 2008 года. Наборы результатов должны исходить из запрашиваемых вами таблиц, поэтому очевидный вывод заключается в том, что вам нужна дополнительная таблица. - тот, который содержит каждый месяц, который вы хотите, как часть вашего результата.

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