Всем привет.
Подскажите. Есть таблица цен. В эту таблицу заноситься цена, только в том случае, если цена за предыдущую дату отличается от текущей. Выглядит это как-то так
"id" "id_product" "price_product" "date"
"1" "999999" "1118" "2019-02-15"
"2" "999999" "1418" "2019-03-15"
При выводе я вывожу все цены вообще, которые относятся к данному id и этот вывод выглядит как-то так
23.03.2019 1200 руб.
20.03.2019 1200 руб.
19.03.2019 1200 руб.
18.03.2019 1200 руб.
17.03.2019 1200 руб.
16.03.2019 1200 руб.
15.03.2019 1200 руб.
и т.д и т.п
Я хочу чтобы, если цена в определенном промежутке дат одна и та же, то просто выводить так
15.03.2019 - 30.03.2019 - 1200р
31.03.2019 - 05.04.2019 - 1300р
06.04.2019 - 30.04.2019 - 1200р
set @current_price = null, @period = 0, @prev_start_date = null;
select min(t.start_date) as start_date, max(t.end_date) as end_date, t.price
from (
select
@prev_start_date,
start_date,
(@prev_start_date - interval 1 day) as end_date,
@prev_start_date := start_date,
@current_price,
price,
if (@current_price <=> price, @period, if(@current_price := price, @period := @period + 1, null)) as period
from test_test
where true
order by start_date desc
) t
group by t.price, t.period
order by start_date desc;
Для правильного вопроса надо знать половину ответа
И что вам мешает так выводить?
1. Берёте первую строку, назовём её строка_1.
2. Из строки_1 берёте дату начала интервала и цену.
3. Если строк больше не осталось, то на п.9
4. Берёте следующую строку, назовём её строка_2.
5. Уменьшаете дату из строки_2 на один день, берёте её как дату конца интервала.
6. Выводите даты и цену.
7. Берёте строку_2 как строку_1
8. На п.3
9. Выводите дату начала из строки_1, текущую дату и цену.
Rsa97, Условие выполняется. Я могу вывести, как описанный выше массив, так и то, что есть в базе
(
[30.04.2019] => 1800
[15.03.2019] => 1200
[15.02.2019] => 1118
)
Массив я вывожу так
foreach($result as $article2) {
if (isset($article1['price_product'])) {
$articles1[date("d.m.Y",strtotime($article2['dtp']))] = (int)$article2['price_product'];
}
}
Запрос мой выводит данные такого типа
"dtc" "id_product" "description" "image_product" "name" "price_product" "dtp"
"2019-02-17" "1111111" "Описание" "1111111.jpg" "Фитнес-браслет Xiaomi Mi Band 2, Black" "1118" "2019-02-15"
"2019-02-16" "2222222" "Описание" "2222222.jpg" "Фитнес-браслет Xiaomi Mi Band 2, Black" "1118" "2019-02-15"
"2019-02-15" "3333333" "Описание" "3333333.jpg" "Фитнес-браслет Xiaomi Mi Band 2, Black" "1118" "2019-02-15"
dtc - это сгененированные дни
dtp - это та уникальная запись ценой из таблицы цен.
Rsa97, Поспешил...Ваш запрос мне вернул такой вот результат
"date" "prevDate" "price_product"
"2019-02-15" "2019-02-14" "1118"
"2019-03-15" "2019-03-14" "1200"
"2019-04-30" "2019-04-29" "1800"
Но должно быть немного не так, а тк
"2019-02-15" - "2019-03-14" - "1118"
"2019-03-15 - "2019-04-29" - "1200"
"2019-04-30" - "2019-04-30" - "1800"
$sql = "SELECT DATE_FORMAT(date,'%d.%m.%Y') as date1, `date`, `date` - INTERVAL 1 DAY AS `prevDate`, `price_product` FROM `prices` WHERE `id_product` = ".$row_product['id_product']." ORDER BY `date`";
Время загрузки страницы достаточно увеличилось с появлением этого запроса. Индекс на id_product стоит.
Rsa97,
ВОТ EXPLAIN
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE prices NULL ref id_product id_product 302 const 20 100.00 Using index condition; Using filesort
arsenaljek, Можно попробовать создать составной индекс (`id_product`, `date`), но не факт, что он даст выигрыш по времени, особенно с учётом того, что выбираются всего 20 строк.
Rsa97, Попробовал. Визуально все осталось так же. Вообще в Mysql Запрос занял 0.0006 сек. Но сама страница стала намного дольше грузиться( Если отключаешь этот запрос, то скорость загрузки страницы заметно вырастает...
Мы тут с коллегами посидели, подумали. SQL запрос получается монструозный с кучей джойнов и агрегатов. Если модифицировать хранилище, то будет гораздо проще. Добавить колонку period_start. При добавлении новой цены, смотреть на предыдущую цену и если она не совпадает с добавляемой писать туда текущую дату. Если совпадает, то писать туда значение period_start из предыдущей записи. И при выборе группировать по period_start.
Sanovskiy, не нужен никакой period_start, если мы соблюдаем выданное в задаче условие "таблицу заносится цена, только в том случае, если цена за предыдущую дату отличается от текущей".
Монструозность запроса можно кардинально сократить, если использовать единственную оконную функцию.