MySQL: заполните пробелы последним известным значением

У меня есть таблица, содержащая глобальные данные о продажах в разные отчетные даты, например:

    event_id   | date          | sales_on_date
    -----------+---------------+----------
    1          | 2015-01-01    | 1000
    1          | 2015-02-01    | 1500
    1          | 2015-03-01    | 1600
    2          | 2015-01-01    | 200
    2          | 2015-02-01    | 500
    3          | 2015-01-01    | 100

И мне нужно написать оператор SELECT для вывода продаж (или последних известных продаж) для каждой даты, например:

    event_id   | date          | sales_on_date
    -----------+---------------+----------
    1          | 2015-01-01    | 1000
    1          | 2015-02-01    | 1500
    1          | 2015-03-01    | 1600
    2          | 2015-01-01    | 200
    2          | 2015-02-01    | 500
    2          | 2015-03-01    | 500
    3          | 2015-01-01    | 100
    3          | 2015-02-01    | 100
    3          | 2015-03-01    | 100

В настоящее время мне нужно сделать запрос SQL, чтобы получить все данные из моей таблицы, а затем использовать процедуру PHP для заполнения пробелов, но кажется, что «чистое» решение SQL было бы намного удобнее и элегантнее.

Любая идея, как это сделать в SQL?


person babarizbak    schedule 10.12.2015    source источник
comment
sql также не может заполнить пробелы. вам понадобится отдельная таблица, содержащая все нужные вам даты, к которым вы можете присоединиться. другими словами, вам в основном нужно реплицировать в sql то, что вы делаете в php.   -  person Marc B    schedule 10.12.2015
comment
Вставка (и поддержка) избыточных данных имеет реальный смысл только в очень специфических ситуациях (производительность в огромных наборах данных, упрощение ужасно сложных вычислений и т. д.). Вы уверены, что не можете воссоздать ожидаемый результат при чтении?   -  person Álvaro González    schedule 10.12.2015
comment
@ Álvaro González Извините, если мой вопрос был неясен, я отредактировал его: мне не нужно вставлять данные в таблицу (это действительно было бы плохой идеей), мне просто нужен запрос SELECT для его вывода!   -  person babarizbak    schedule 10.12.2015


Ответы (1)


Это немного сложно, потому что запрос состоит из двух частей. Первый генерирует все строки. Второй заполняет их. Первый - это CROSS JOIN. Второй коррелированный подзапрос:

select e.event_id, d.date,
       (select t.sales_on_date
        from t
        where t.event_id = e.event_id and t.date <= d.date
        order by t.date desc
        limit 1
       ) as sales_on_date
from (select distinct event_id from t) e cross join
     (select distinct date from t) d
order by e.event_id, d.date;
person Gordon Linoff    schedule 10.12.2015