Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Оптимизация выборки. Можно ли чем-то заменить подзапросы?  [new]
eonae
Member

Откуда:
Сообщений: 17
Уважаемые знатоки!

Помогите пожалуйста фронтендеру )

В базе данных хранится классификация продуктов. Сами признаки и возможные значения которые они могут принимать динамические, поэтому всё хранится в нескольких таблицах:

Products
   ItemID
   ....

Classifications
   ClassificationId
   Name
   ....
ClassificationOptions
   OptionId
   ClassificationId
   Name
   ....

ClassificationBindings
   ProductId
   ClassificationId
   OptionId
   ....


А теперь я хочу собрать определённые классификации, чтобы получилась таблица вида:
productName | classification1 | classification2 | ......

Умнее, чем

select
	ItemName,
	Classification1= (select top (1) o.Name 
			from ClassificationBindings b
			left join ClassificationOptions o on b.optionId = o.optionId
			left join Classifications c on c.classificationId = b.classificationId
			where c.classificationId = 'C1' and p.ItemId = b.productId and b.Disabled is null)
        .....

from Products p 


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

Подскажите пожалуйста, как сделать оптимальнее?

Если суть задачи не понятна - поясню..

Заранее спасибо!
26 окт 19, 20:03    [22003313]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация выборки. Можно ли чем-то заменить подзапросы?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36691
Вот top 1 без order by это даже не костыль, а еще хуже.
А коррелированные подзапросы -- это вполне нормальное решение.
26 окт 19, 20:06    [22003315]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация выборки. Можно ли чем-то заменить подзапросы?  [new]
eonae
Member

Откуда:
Сообщений: 17
Гавриленко Сергей Алексеевич,

Оrder by есть конечно - забыл написать.

Честно говоря, меня не вполне устраивает скорость.. может быть можно как-то быстрее?
26 окт 19, 20:09    [22003317]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация выборки. Можно ли чем-то заменить подзапросы?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36691
eonae,

Наверняка можно.
26 окт 19, 20:18    [22003323]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация выборки. Можно ли чем-то заменить подзапросы?  [new]
invm
Member

Откуда: Москва
Сообщений: 9116
eonae
может быть можно как-то быстрее?
Может и можно.
Только по приведенным фрагментам кода очень трудно догадаться, что же вы хотите получить...
26 окт 19, 21:09    [22003351]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация выборки. Можно ли чем-то заменить подзапросы?  [new]
eonae
Member

Откуда:
Сообщений: 17
invm,

Постараюсь пояснить:

В таблице Classifications хранятся признаки, которые могут быть у продукта. Пример признака: "Тип" или "Горячее"

INSERT INTO Classifications (id, name) VALUES
(1, 'Тип')
(2, 'Прожарка')


В таблице ClassificationOptions хранятся возможные значения, которые могут принимать признаки:

INSERT INTO ClassificationOptions (id, classification_id, name) VALUES
(1, 1, 'Еда')            -- Тип
(2, 1, 'Напиток')     -- Тип
(3, 2, 'Слабо')        -- Прожарка
(4, 2, 'Средне')      -- Прожарка
(5, 2, 'Сильно')      -- Прожарка


В таблице ClassificationBindings хранятся привязки конкретных продуктов из таблицы Products (упрощённо id и name):

-- product_id = 5235 - Стейк

INSERT INTO ClassificationBindings (id, product_id, classification_id, option_id) VALUES
(1, 5235, 1, 1) -- Тип: Еда
(2, 5235, 2, 4) -- Прожарка: Средне


Теперь я хочу запросить к каким категориям относятся мои продукты в таблице Products.

Я могу сделать такой запрос:

SELECT
     p.name AS Продукт
     с.name AS Категория
     o.name AS Значение
FROM Products p
LEFT JOIN ClassificationBindings b ON p.id = b.product_id
LEFT JOIN ClassificationOptions  o ON b.option_id = o.id
LEFT JOIN Classifications c ON b.classification_id = b.classification_id


Получу в результате:

-------------------------------------------------------
Продукт | Категория | Значение
-------------------------------------------------------
Стейк | Тип | Еда
Стейк | Прожарка | Средняя
-------------------------------------------------------

Но хотел бы получить таблицу такого вида:

---------------------------------------------------
Продукт | Тип | Прожарка
---------------------------------------------------
Стейк Еда Средняя
---------------------------------------------------

Хотя в таблице категорий количество категорий может меняться динамически, в выборке мне это не требуется. Я заранее знаю какие классификации мне нужно подтянуть в качестве столбцов.

Один способ, как добиться выполнения моей задачи я уже указал выше.

Если есть более оптимальный с точки зрения производительности, буду рад, если наведётся на мысль. Писать за меня не обязательно )

С уважением.
26 окт 19, 23:15    [22003448]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация выборки. Можно ли чем-то заменить подзапросы?  [new]
invm
Member

Откуда: Москва
Сообщений: 9116
eonae,

См. pivot
26 окт 19, 23:23    [22003451]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация выборки. Можно ли чем-то заменить подзапросы?  [new]
eonae
Member

Откуда:
Сообщений: 17
Благодарю, PIVOT помог.
27 окт 19, 18:29    [22003707]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить