SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 28.07.2016 14:55:33

Udav
Участник
Зарегистрирован: 28.07.2016
Сообщений: 5

помогите пожалуйста с запросом

Имеется две таблицы цен на товары:

Таблица `default_price`, содержащая два столбца: идентификатор товара и цена по-умолчанию:
id        price
10        3000
34        5000
53        5000
Таблица `day_price`, содержащая три столбца: идентификатор товара, дата, особая цена на дату:
id        price        date
53        3500        01.10.2014
53        5500        05.10.2014
53        1500        09.10.2014
53        2500        10.10.2014
53        2500        11.10.2014
53        2500        12.10.2014
10        3500        02.10.2014

Необходимо, чтобы SQL-запрос по заданному идентификатору товара (например = 53) и датам начала и конца периода (например с 01 по 10.10.2012), возвращал таблицу следующего вида:
date                price        price_type
01.10.2014      3500        особая цена
02.10.2014      5000        цена по-умолчанию
03.10.2014       5000        цена по-умолчанию
04.10.2014       5000        цена по-умолчанию
05.10.2014      5500        особая цена
06.10.2014       5000        цена по-умолчанию
07.10.2014       5000        цена по-умолчанию
08.10.2014       5000        цена по-умолчанию
09.10.2014      1500        особая цена
10.10.2014      2500        особая цена
То есть для каждой даты из периода выбирал либо цену по-умолчанию, если на заданный день нет особой цены, либо особую цену,
если таковая имеется, с указанием соответствующего источника цены для каждого дня.

вот этот вариант не подходит:

SELECT day_price.date, day_price.price,
CASE
    WHEN default_price.price = day_price.price
    THEN 'цена по-умолчанию'
    ELSE 'особая цена'
    END as price_type
FROM day_price
JOIN default_price ON day_price.id = default_price.id
WHERE default_price.id = 53 AND day_price.date BETWEEN '2014-10-01' AND '2014-10-20'
ORDER by date ASC

ошибка в том, что в таблице результата, дата берется из интервала BETWEEN '2014-10-01' AND '2014-10-20' с шагом 1 день. Как это сделать ума не прилажу. Хотя бы куда копать пните.

Неактивен

 

#2 28.07.2016 20:28:03

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: помогите пожалуйста с запросом

вам нужно иметь опорную таблицу с датами, например, за год или сколько вам нужно
`таблица с датами` join `day_price` join  `default_price`

Неактивен

 

#3 28.07.2016 20:59:44

Udav
Участник
Зарегистрирован: 28.07.2016
Сообщений: 5

Re: помогите пожалуйста с запросом

vasya написал:

вам нужно иметь опорную таблицу с датами, например, за год или сколько вам нужно
`таблица с датами` join `day_price` join  `default_price`

немного продвинулся в решении вопроса, не успел ответить )
во процедура:
DROP PROCEDURE IF EXISTS create_temp_table;
DELIMITER //
CREATE PROCEDURE create_temp_table(
        IN begin_date DATE,
        IN end_date DATE
    )
    DETERMINISTIC   
BEGIN   
    SET @last_date = begin_date;   
    DROP TABLE IF EXISTS temp_calendar;   
    CREATE TEMPORARY TABLE temp_calendar(
           date DATE NOT NULL,
           KEY days (date)
    ) ENGINE = MyIsam;   
    WHILE @last_date <= end_date DO
       insert into temp_calendar(date) values(@last_date);
       SET @last_date = DATE_ADD(@last_date, interval 1 day);
    END WHILE; 
END //

она создает временную таблицу.
Теперь у меня глупая ситуация... не могу ее использовать в запросе select, модифицировать тот, что в первом посте, . Помогите бедолаге пожалуйста...

Неактивен

 

#4 28.07.2016 21:27:34

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: помогите пожалуйста с запросом

не проверял, но что-то вроде:

SELECT temp_calendar.date, ifnull(day_price.price,default_price.price), if(day_price.price is null, 'цена по-умолчанию', 'особая цена') as price_type
FROM temp_calendar LEFT JOIN day_price USING(`date`), default_price
WHERE default_price.id = 53 AND day_price.id = 53 AND day_price.date BETWEEN '2014-10-01' AND '2014-10-20'
ORDER by temp_calendar.date ASC

Неактивен

 

#5 28.07.2016 21:32:01

Udav
Участник
Зарегистрирован: 28.07.2016
Сообщений: 5

Re: помогите пожалуйста с запросом

vasya написал:

не проверял, но что-то вроде:

SELECT temp_calendar.date, ifnull(day_price.price,default_price.price), if(day_price.price is null, 'цена по-умолчанию', 'особая цена') as price_type
FROM temp_calendar LEFT JOIN day_price USING(`date`), default_price
WHERE default_price.id = 53 AND day_price.id = 53 AND day_price.date BETWEEN '2014-10-01' AND '2014-10-20'
ORDER by temp_calendar.date ASC

остаются "дырки", спасибо за подсказки

Неактивен

 

#6 28.07.2016 21:49:28

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: помогите пожалуйста с запросом

сделайте пример на http://sqlfiddle.com/ с тестовыми данными
temp_calendar  придется сделать постоянной для примера

Неактивен

 

#7 28.07.2016 22:06:37

Udav
Участник
Зарегистрирован: 28.07.2016
Сообщений: 5

Re: помогите пожалуйста с запросом

vasya написал:

сделайте пример на http://sqlfiddle.com/ с тестовыми данными
temp_calendar  придется сделать постоянной для примера

как то так: http://sqlfiddle.com/#!9/346152

Неактивен

 

#8 28.07.2016 22:29:41

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: помогите пожалуйста с запросом

SELECT temp_calendar.date,
ifnull(day_price.price,default_price.price),
if(day_price.price is null, 'цена по-умолчанию', 'особая цена') as price_type
FROM temp_calendar LEFT JOIN day_price
ON (temp_calendar.`date` = day_price.`date` AND day_price.id = 53
AND day_price.date BETWEEN '2014-10-01' AND '2014-10-20'), default_price
WHERE default_price.id = 53
ORDER by temp_calendar.date ASC;

Неактивен

 

#9 28.07.2016 22:38:58

Udav
Участник
Зарегистрирован: 28.07.2016
Сообщений: 5

Re: помогите пожалуйста с запросом

vasya написал:

SELECT temp_calendar.date,
ifnull(day_price.price,default_price.price),
if(day_price.price is null, 'цена по-умолчанию', 'особая цена') as price_type
FROM temp_calendar LEFT JOIN day_price
ON (temp_calendar.`date` = day_price.`date` AND day_price.id = 53
AND day_price.date BETWEEN '2014-10-01' AND '2014-10-20'), default_price
WHERE default_price.id = 53
ORDER by temp_calendar.date ASC;

эхх а я вот почти успел ) правда id еще не скрылось )

SELECT temp_calendar.date,
        if(day_price.price is null, 'цена по-умолчанию', 'особая цена') as price_type,
        if (day_price.price is null,(SELECT default_price.price from default_price WHERE default_price.id=53), day_price.price) as price,
        CASE day_price.id
            WHEN day_price.id is null
            THEN 53
            ELSE 53
            END id
FROM temp_calendar
LEFT JOIN day_price ON temp_calendar.date = day_price.date
LEFT JOIN default_price using (id)
WHERE day_price.id = 53 or day_price.id is null
ORDER by date ASC


СПАСИБО человечище огромное!

ЗЫ: итоговый вариант:
DROP PROCEDURE IF EXISTS create_temp_table;
DELIMITER //
CREATE PROCEDURE create_temp_table(
        IN begin_date DATE,
        IN end_date DATE
    )
    DETERMINISTIC    
BEGIN    
    SET @last_date = begin_date;    
    DROP TABLE IF EXISTS temp_calendar;    
    CREATE TEMPORARY TABLE temp_calendar(
           date DATE NOT NULL,
           KEY days (date)
    ) ENGINE = innoDB;    
    WHILE @last_date <= end_date DO
       insert into temp_calendar(date) values(@last_date);
       SET @last_date = DATE_ADD(@last_date, interval 1 day);
    END WHILE;  
END //
CALL create_temp_table('2014-10-01','2014-10-20');
SELECT temp_calendar.date,
IF(day_price.price is null, 'цена по-умолчанию', 'особая цена') as price_type,
IF (day_price.price is null,(SELECT default_price.price from default_price WHERE default_price.id=53), day_price.price) as price      
FROM temp_calendar LEFT JOIN day_price
ON (temp_calendar.`date` = day_price.`date` AND day_price.id = 53
AND day_price.date BETWEEN '2014-10-01' AND '2014-10-20'), default_price
WHERE default_price.id = 53
ORDER by temp_calendar.date ASC;

Отредактированно Udav (28.07.2016 23:10:00)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson