powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите составить супер сложный запрос
21 сообщений из 21, страница 1 из 1
Помогите составить супер сложный запрос
    #39898227
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте! Возможно ли такую выборку одним запросом сделать?
Есть 3 таблицы:

products
_____
id | name
1 | tovar1
2 | tovar2
3 | tovar3
4 | tovar4
5 | tovar5

sklads
_____
id | name | delivery_time (срок доставки, дней)
1 | sklad1 | 10
2 | sklad2 | 20
3 | sklad3 | 30

product_to_sklad
_____
id_product | id_sklad | price (цена товара на складе) | count (количество товара на складе)
1 | 1 | 1000 | 4
1 | 2 | 2000 | 5
2 | 1 | 3000 | 3
2 | 2 | 4000 | 4
3 | 1 | 5000 | 1
3 | 3 | 6000 | 3
3 | 2 | 7000 | 3

У каждого товара из таблицы products может быть несколько складов из таблицы sklads, для этого создана таблица product_to_sklad. Нужно при выборке товаров выбрать только 1 склад для каждого товара, удовлетворяющий нескольким условиям:
1. Количество товара на складе не менее 4 штук и минимальный срок доставки
2. Если нет склада удовлетворяющего первое условие, то выбирать склад с наибольшим количеством и наименьшим сроком доставки
3. Если склад не выбран первым двум условиям, то товар выводить, но без данных по складу

На выходе должно получиться:

id | name | id_sklad | delivery_time | price | count
1 | tovar1 | 1 | 10 | 1000 | 4
2 | tovar2 | 2 | 20 | 4000 | 4
3 | tovar3 | 2 | 20 | 7000 | 3
4 | tovar4 | | | |
5 | tovar5 | | | |

Может я преувеличил с супер сложностью, но у меня в 1 запрос это все реализовать не получается, реализовал так, сначала выбираю все товары, далее foreach по товарам с выборкой всех складов и выбор подходящего склада php-условиями, все работает замечательно, за исключением того, что нет возможности сделать сортировку товаров по цене и количеству, так как в первичной выборке этого нет.
Помогите пожалуйста гуру mysql-запросов!
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898311
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir_KZN
1. Количество товара на складе не менее 4 штук и минимальный срок доставки

Это два условия. И результат наличия такой записи зависит от порядка их применения.

Vladimir_KZN
2. Если нет склада удовлетворяющего первое условие, то выбирать склад с наибольшим количеством и наименьшим сроком доставки
То же самое.
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898314
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На всякий случай - сделал fiddle . Вдруг кто захочет покрутить... В принципе-то несложная задача, если сделать чётким условие.
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898415
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina, спасибо за ответ. Уточню условие, буду использовать if/else для большей ясности
if (Количество товара на складе не менее 4 штук) {
выбираем с минимальным сроком доставки
} else if (выбираем склады с наибольшим количеством) {
выбираем с минимальным сроком доставки
}
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898441
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лучше так:

1. Если имеются склады с количеством не менее 4 - вернуть склад с наименьшим сроком доставки, если таких несколько, вернуть склад с [указать однозначное условие, либо продолжить цепочку]

иначе

2. Если имеются склады с этим товаром - вернуть склад с наибольшим количеством, если таких несколько - вернуть склад с наименьшим сроком доставки, если таких несколько, вернуть склад с [указать однозначное условие, либо продолжить цепочку]

иначе

3. Вернуть NULL.

Заполните недостающее. Условие может быть любым (да хоть первый в алфавитном порядке), и необязательно одно и то же в разных пунктах. Условие "первый попавшийся" - нежелательно.
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898445
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
Все склады имеют разный срок доставки, но на всякий случай тогда дополню
Как то так:

1. Если имеются склады с количеством не менее 4 - вернуть склад с наименьшим сроком доставки, если таких несколько, вернуть склад первый в алфавитном порядке

иначе

2. Если имеются склады с этим товаром - вернуть склад с наибольшим количеством, если таких несколько - вернуть склад с наименьшим сроком доставки, если таких несколько, вернуть склад первый в алфавитном порядке

иначе

3. Вернуть NULL.

Также я попытался реализовать запрос, выводит только 1 товар, далее разобраться не могу. Вот что получилось

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT p.id, p.name, s.id AS id_sklad, s.delivery_time, p2s.price, p2s.cnt FROM products p
LEFT JOIN product_to_sklad p2s ON (p.id = p2s.id_product) 
LEFT JOIN sklads s ON (s.id = p2s.id_sklad)
WHERE if (
p2s.cnt >=4,
s.delivery_time = (SELECT min(s2.delivery_time) FROM sklads s2 
        LEFT JOIN product_to_sklad p2s2 ON (s2.id = p2s2.id_sklad) 
        WHERE p2s2.id_product = p.id),
p2s.cnt = (SELECT max(p2s3.cnt) FROM product_to_sklad p2s3
        WHERE p2s3.id_product = p.id) 
        AND s.delivery_time = (
                SELECT min(s4.delivery_time) FROM sklads s4
                LEFT JOIN product_to_sklad p2s4 ON (s4.id = p2s4.id_sklad)
                WHERE p2s4.id_product = p.id)
)
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898505
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina, буду очень признателен, если вы мне поможете
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898518
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
WITH 
cte AS (
SELECT DISTINCT
       ps.id_product,
       CASE WHEN SUM(ps.cnt>=4) OVER (PARTITION BY ps.id_product) >0
            THEN FIRST_VALUE(ps.id_sklad) OVER (PARTITION BY ps.id_product
                                                ORDER BY ps.cnt<4,
                                                         s.delivery_time ASC, 
                                                         s.name ASC) 
            ELSE FIRST_VALUE(ps.id_sklad) OVER (PARTITION BY ps.id_product
                                                ORDER BY ps.cnt DESC, 
                                                         s.delivery_time ASC, 
                                                         s.name ASC)
            END id_sklad
FROM product_to_sklad ps, sklads s
WHERE ps.id_sklad = s.id
)
SELECT p.name, cte.id_sklad, s.delivery_time, ps.price, ps.cnt `count`
FROM products p
LEFT JOIN cte ON p.id = cte.id_product
LEFT JOIN sklads s ON s.id = cte.id_sklad
LEFT JOIN product_to_sklad ps ON (ps.id_product, ps.id_sklad) = (cte.id_product, cte.id_sklad)


fiddle
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898528
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina, Просто супер, работает, спасибо Вам!!! Вот только проблема, у меня MySQL 5.7. Как можно адаптировать запрос под мою версию?
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898538
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir_KZN
у меня MySQL 5.7. Как можно адаптировать запрос под мою версию?

Можно. Заменяйте оконные функции соотв. коррелированными подзапросами, а итоговый CTE переносите в секцию FROM.

Но имхо разумнее таки обновить версию - сколько можно на старье-то работать?
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898560
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina, Как то так?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SELECT p.name, cte.id_sklad, s.delivery_time, ps.price, ps.cnt `count`
FROM products p
LEFT JOIN (SELECT DISTINCT
       ps.id_product,
       CASE WHEN SUM(ps.cnt>=4) OVER (PARTITION BY ps.id_product) >0
            THEN FIRST_VALUE(ps.id_sklad) OVER (PARTITION BY ps.id_product
                                                ORDER BY ps.cnt<4,
                                                         s.delivery_time ASC, 
                                                         s.name ASC) 
            ELSE FIRST_VALUE(ps.id_sklad) OVER (PARTITION BY ps.id_product
                                                ORDER BY ps.cnt DESC, 
                                                         s.delivery_time ASC, 
                                                         s.name ASC)
            END id_sklad
FROM product_to_sklad ps, sklads s
WHERE ps.id_sklad = s.id
) cte
LEFT JOIN cte ON p.id = cte.id_product
LEFT JOIN sklads s ON s.id = cte.id_sklad
LEFT JOIN product_to_sklad ps ON (ps.id_product, ps.id_sklad) = (cte.id_product, cte.id_sklad)



Ругается на "OVER (PARTITION ... "
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898565
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir_KZN
Ругается на "OVER (PARTITION ... "
Ну я же вроде сказал:
Akina
Заменяйте оконные функции соотв. коррелированными подзапросами
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898572
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina, эх, если бы я знал что такое оконные функции... , то наверное бы смог заменить. А так я прошу вашей помощи снова
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898588
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не, слишком это муторно. Мне - лень.
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898592
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

Я так понимаю это
Код: sql
1.
 OVER (PARTITION BY ps.id_product)

оконная функция? Может на словах объясните на какой подзапрос ее нужно поменять?
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898698
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кто то еще может предложить решение? Для MySQL 5.7?
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898703
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir_KZN

Нужно при выборке товаров выбрать только 1 склад для каждого товара, удовлетворяющий нескольким условиям:
1. Количество товара на складе не менее 4 штук и минимальный срок доставки
2. Если нет склада удовлетворяющего первое условие, то выбирать склад с наибольшим количеством и наименьшим сроком доставки
3. Если склад не выбран первым двум условиям, то товар выводить, но без данных по складу


Вот эти условия

author1. минимальный срок доставки
2. Если нет склада удовлетворяющего первое условие, то выбирать склад с наибольшим количеством и наименьшим сроком доставки
3. Если склад не выбран первым двум условиям, то товар выводить, но без данных по складу


очень плохо будет делать через один запрос

Даже если это можно написать, (в чём я не сомневаюсь) делать это не нужно,
напиши процедуру или программную логику.
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898746
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv
Vladimir_KZN

Нужно при выборке товаров выбрать только 1 склад для каждого товара, удовлетворяющий нескольким условиям:
1. Количество товара на складе не менее 4 штук и минимальный срок доставки
2. Если нет склада удовлетворяющего первое условие, то выбирать склад с наибольшим количеством и наименьшим сроком доставки
3. Если склад не выбран первым двум условиям, то товар выводить, но без данных по складу


Вот эти условия

author1. минимальный срок доставки
2. Если нет склада удовлетворяющего первое условие, то выбирать склад с наибольшим количеством и наименьшим сроком доставки
3. Если склад не выбран первым двум условиям, то товар выводить, но без данных по складу


Не совсем понял что вы имеете ввиду
MasterZiv

очень плохо будет делать через один запрос

Даже если это можно написать, (в чём я не сомневаюсь) делать это не нужно,
напиши процедуру или программную логику.

Нужно именно одним запросом

Вы можете мне помочь? Под MySQL 5.7?
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39898783
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Задачка актуальна. Прошу помочь составить запрос
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39900760
Vladimir_KZN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Up
...
Рейтинг: 0 / 0
Помогите составить супер сложный запрос
    #39903456
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не совсем понял что вы имеете ввиду

Что же тут может быть непонятного? Русским же языком написано.

MasterZiv

очень плохо будет делать через один запрос

Даже если это можно написать, (в чём я не сомневаюсь) делать это не нужно,
напиши процедуру или программную логику.


Нужно именно одним запросом

НЕ НУЖНО одним запросом

Вы можете мне помочь? Под MySQL 5.7?

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


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