Вывод пустых строк вошедших в диапазон Between - MySQL
Формулировка задачи:
Есть запрос
Результатом его является
date | price | price_type
01.08.2017 | 3500 | Особенная цена
05.08.2017 | 4500 | Особенная цена
08.08.2017 | 4500 | Особенная цена
....
Нужно получить таблицу вида:
01.08.2017 | 3500 | Особенная цена
02.08.2017 | null | null
03.08.2017 | null | null
04.08.2017 | null | null
05.08.2017 | 4500 | Особенная цена
06.08.2017 | null | null
07.08.2017 | null | null
08.08.2017 | 4500 | Особенная цена
Уже "обгуглился"
SELECT DATE_FORMAT(day_price.date,'%d.%m.%Y') AS DATE, day_price.price, IF((default_price.price - day_price.price)=0, 'Цена по-умолчанию', 'Особая цена' ) AS price_type FROM day_price INNER JOIN default_price ON day_price.id=default_price.id WHERE day_price.date BETWEEN '2017-08-01' AND '2017-08-12' AND day_price.id = '53'
Решение задачи: «Вывод пустых строк вошедших в диапазон Between»
textual
Листинг программы
CREATE TEMPORARY TABLE `temp` (
`date` DATE NOT NULL,
PRIMARY KEY (`date`)
);
delimiter //;
CREATE PROCEDURE `date_between` ( dfrom DATE, dto DATE )
BEGIN
DECLARE curr DATE;
SET curr = dfrom;
WHILE ( curr <= dto ) DO
INSERT INTO `temp` (DATE) VALUES (curr);
SET curr = curr + INTERVAL 1 DAY;
END WHILE;
END//;
delimiter ;
CALL date_between('2017-08-01', '2017-08-12');
SET @id = (SELECT price FROM default_price WHERE id = '53');
DROP PROCEDURE `date_between`;
SELECT DATE_FORMAT(temp.date,'%d.%m.%Y') AS DATE,
IF(day_price.id != '53' OR day_price.id IS NULL, @id, day_price.price) AS price,
IF(day_price.id != '53' OR day_price.id IS NULL, 'Цена по-умолчанию', 'Особенная цена') AS price_type
FROM temp
LEFT JOIN day_price ON temp.date=day_price.date
LEFT JOIN default_price ON day_price.id=default_price.id
ORDER BY temp.date ASC
Объяснение кода листинга программы
- Создаётся временная таблица
tempс одним столбцомdateтипа DATE. - Устанавливается delimiter для того чтобы не возникало конфликтов с названиями других процедур или таблиц в базе данных.
- Создаётся процедура
date_betweenс двумя параметрами типа DATE —dfromиdto. - В процедуре объявляется переменная
currтипа DATE и инициализируется значениемdfrom. - В цикле WHILE
currменьше или равноdtoвставляется текущее значениеcurrв таблицуtemp. - Значение
currувеличивается на 1 день с помощью оператора INTERVAL. - Выполняется DROP PROCEDURE для удаления процедуры
date_betweenпосле её использования. - Выполняется CALL date_between('2017-08-01', '2017-08-12') для заполнения таблицы
tempданными. - Устанавливается значение переменной
@idравным цене по умолчанию для товара с id равным '53'. - Выполняется SELECT запрос с несколькими условиями для вывода данных в нужном формате.
- В запросе используется функция DATE_FORMAT для вывода даты в формате день.месяц.год.
- Используется функция IF для вывода цены по умолчанию или особой цены в зависимости от наличия или отсутствия записи в таблице
day_priceдля конкретной даты. - Выполняется LEFT JOIN с таблицами
day_priceиdefault_priceдля получения нужных данных. - Запрос упорядочивается по дате в возрастающем порядке.