powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / помогите пожалуйста с запросом
19 сообщений из 19, страница 1 из 1
помогите пожалуйста с запросом
    #39282004
ud_aw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Имеется две таблицы цен на товары:

Таблица `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 особая цена
То есть для каждой даты из периода выбирал либо цену по-умолчанию, если на заданный день нет особой цены, либо особую цену,
если таковая имеется, с указанием соответствующего источника цены для каждого дня.

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

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
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 день. Как это сделать ума не прилажу. Хотя бы куда копать пните.
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39282066
MikkiMouse
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ud_aw,

Опорная таблица дат спасет гиганта мысли, отца русской демократии
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39282107
nrmBeginner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В обеих таблицах список товаров идентичен?
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39282114
ud_aw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
nrmBeginner,
нет
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39282119
ud_aw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
точнее в условии ничего не сказано про идентичность, выделена только связь между таблицами по id
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39282205
ud_aw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
задача прояснилась, создаем временную таблицу:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
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 //



теперь другая проблема, как ее прилепить (JOIN) в запросе, ругается что такой таблице в БД нет...

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT create_temp_table('2014-10-01','2014-10-20'), 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
LEFT JOIN temp_calendar ON temp_calendar.date = day_price.date
WHERE default_price.id = 53 AND day_price.date BETWEEN '2014-10-01' AND '2014-10-20'
ORDER by date ASC
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39282290
ud_aw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
проблема решена:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
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;
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39282348
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ud_aw,

сделайте нормальную, не временную таблицу
она вам ещё много раз пригодится, зачем зря сервер напрягать
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39283013
nrmBeginner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ud_aw,

Писец, на кой черт столько ненужного для такой элементарной задачи? Вот:
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT default_price.id,
	IF(dp.id IS NULL, '-', dp.dt) AS Когда,
	IF(NOT dp.id IS NULL AND dp.dt = CURDATE(),dp.price, default_price.price) AS Цена,
	IF(NOT dp.id IS NULL AND dp.dt = CURDATE(),'особая цена', 'цена по-умолчанию') AS Тип
FROM default_price LEFT OUTER JOIN day_price AS dp
ON default_price.id = dp.id
ORDER BY dp.dt;



Если что, вот исходные данные:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE TABLE default_price (
	id		INTEGER UNSIGNED NOT NULL PRIMARY KEY,
	price	DECIMAL(12,2) NOT NULL
);

CREATE TABLE day_price (
	id		INTEGER UNSIGNED NOT NULL PRIMARY KEY,
	price	DECIMAL(12,2) NOT NULL,
	dt		DATE NOT NULL
);

INSERT INTO default_price VALUES(1, 10.40);
INSERT INTO default_price VALUES(2, 15.00);
INSERT INTO default_price VALUES(3, 16.90);
INSERT INTO default_price VALUES(4, 21.50);
INSERT INTO default_price VALUES(5, 8.60);
INSERT INTO default_price VALUES(6, 19.00);
INSERT INTO default_price VALUES(7, 38.00);
INSERT INTO day_price VALUES(1, 9.40, CURRENT_DATE()-1);
INSERT INTO day_price VALUES(3, 11.00 CURRENT_DATE());
INSERT INTO day_price VALUES(5, 6.50, CURRENT_DATE()-1);
INSERT INTO day_price VALUES(7, 30.00, CURRENT_DATE());

...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39283603
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nrmBeginner,

а теперь внимательно читаем условие исходной задачи, конкретнее - что именно надо получить...
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39284176
nrmBeginner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglir,

Если ты узрел какой-то тайный смысл между строк то не ленись поделиться. Иначе треп.
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39284280
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nrmBeginner, нет там никакого тайного смысла, и между строк читать необязательно. Достаточно посмотреть на желаемый результат.
высё ещё не дошло? твой запрос выдаёт совершенно не то, чего хочет ТС
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39284322
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
насчёт опорной таблицы дат... не уверен что она нужна.
причина - мы берём таблицу опорную за основу - тоесть её читаем целиком, а по индексам уже на поля даты лепим остальные.

остаётся вопрос, откуда брать таблицу опорную, с винчестера, или генерировать на лету. второе наверно побыстрее будет.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
select @s:=@s+1

from

(select 1 union select 2 union select 3 union select 4 union select 5) t1,
(select 1 union select 2 union select 3 union select 4 union select 5) t2,
(select 1 union select 2 union select 3 union select 4 union select 5) t3,
(select 1 union select 2 union select 3 union select 4 union select 5) t4,
(select 1 union select 2 union select 3 union select 4 union select 5) t5,
(select 1 union select 2 union select 3 union select 4 union select 5) t6,
(select 1 union select 2 union select 3 union select 4 union select 5) t7,
(select 1 union select 2 union select 3 union select 4 union select 5) t8,
(select @s:=0) tt

/* Affected rows: 0  Знайдено записів: 390 625  Попередження: 0  Тривалість 1 query: 0,015 sec. (+ 0,967 sec. network) */
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39284324
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

извините, не обратил внимание.
/* Affected rows: 0 Знайдено записів: 390 625 Попередження: 0 Тривалість 1 query: 0,015 sec. (+ 0,967 sec. network) */

/* Affected rows: 0 Найдено записей: 390 625 Предупреждений: 0 Продолжительность 1 query: 0,015 sec. (+ 0,967 sec. network) */
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39284326
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
390к опорных дней думаю любому хватит :) этож более 1000 лет :)
а считывать опорную из файла... точно в 15 милисикунд не уложится.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
set @startDate = '1945-01-01';
select @startDate + INTERVAL o.ad DAY as 'Date' 

from (
select @s:=@s+1 as 'ad'

from

(select 1 union select 2 union select 3 union select 4 union select 5) t1,
(select 1 union select 2 union select 3 union select 4 union select 5) t2,
(select 1 union select 2 union select 3 union select 4 union select 5) t3,
(select 1 union select 2 union select 3 union select 4 union select 5) t4,
(select 1 union select 2 union select 3 union select 4 union select 5) t5,
(select 1 union select 2 union select 3 union select 4 union select 5) t6,
(select 1 union select 2 union select 3 union select 4 union select 5) t7,
(select 1 union select 2 union select 3 union select 4 union select 5) t8,
(select @s:=0) tt) o

/* 2 queries: 0,031 sec. (+ 0,889 sec. network)*/
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39284328
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
set @startDate = '1945-01-01';

select @startDate + INTERVAL (@s:=@s+1) DAY as 'Date'

from

(select 1 union select 2 union select 3 union select 4 union select 5) t1,
(select 1 union select 2 union select 3 union select 4 union select 5) t2,
(select 1 union select 2 union select 3 union select 4 union select 5) t3,
(select 1 union select 2 union select 3 union select 4 union select 5) t4,
(select @s:=0) tt



это правильный запрос с датами, тот что выше 200 милисекунд выполняется
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39284424
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453а считывать опорную из файла... точно в 15 милисикунд не уложится.Ну какбэ кэш никто пока не отменил. Разницы по скорости с созданием на лету не будет никакой, зато не придётся вкорячивать в запросы эту монструозину с кучей юнионов.
Дело вкуса по сути.
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39284533
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tanglir,

да, но с практической точки зрения, если отчёт за 90 дней. то врядли подобный запрос частый...в кеше ничего хранится не будет. а если и кешировать, то уже сам ответ сервера клиенту(сервиса а не бд)
...
Рейтинг: 0 / 0
помогите пожалуйста с запросом
    #39285029
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453,

но если запрос разовый, то можно и подождать несколько лишних миллисекунд :)
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / помогите пожалуйста с запросом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]