Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум на Исходниках.RU > Базы данных: SQL > Необходима помощь с составлением SQL-запроса |
Автор: Костик+ 12.07.23, 13:32 |
Доброго времени суток, всем! Собственно, сабж. Есть таблица вида: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> ProductId |AttrId |AttrValueId ------------+--------------+----------------- 1 |5 |1010 1 |7 |954 1 |8 |352 1 |9 |21057 1 |14 |221 2 |4 |997 2 |5 |2350 2 |8 |352 2 |9 |20533 2 |14 |232 3 |5 |1010 3 |8 |352 3 |9 |27044 4 |5 |1010 4 |7 |964 4 |8 |331 4 |14 |219 //... Каждый ProductId может иметь только один уникальный AttrId. Необходимо выбрать из таблицы все ProductId, удовлетворяющие условию, когда определённые атрибуты содержат соответствующие Value. Например, выбрать товары, в для которых AttrId 5 содержит Value 1010 и AttrId 8 содержит Value 352: 5 => 1010 и 8 => 352 Т.е., получается что-то типа такого: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> SELECT ProductID FROM ProductTable WHERE (AttrId = 5 AND AttrValueId = 1010) AND (AttrId = 8 AND AttrValueId = 352) В результате выполнения подобного запроса для таблицы из примера выше, получим выборку: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> ProductId ---------- 1 3 ProductId 2 и 4 не подойдут, т.к. для них выполняется только одно из условий. БД: MSSQL. Надеюсь, правильно сформулировал свою мысль. |
Автор: Majestio 12.07.23, 13:51 |
В таблице ProductId = 1 имеет пять AttrId ... дальше не читал |
Автор: Akina 12.07.23, 16:20 |
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> SELECT ProductID FROM ProductTable WHERE ( AttrId, AttrValueId ) IN ( (5, 1010), (8, 352) ) GROUP BY ProductID HAVING COUNT( /* DISTINCT */ AttrId ) = 2 |
Автор: Костик+ 12.07.23, 16:23 |
Да, спасибо. Резонное замечание. Прошу прощения, с утра не выспался. Имеется ввиду, что параметр AttrId уникален для каждого ProductId. Т.е. ситуация: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> ProductId | AttrId ----------+-------- 1 |5 1 |6 1 |7 //... может быть, а: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> ProductId | AttrId ----------+-------- 1 |4 1 |4 1 |4 не может. |
Автор: Majestio 12.07.23, 17:17 |
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> SELECT ProductID FROM ProductTable WHERE (AttrId = 5 AND AttrValueId = 1010) OR -- <--- тут (AttrId = 8 AND AttrValueId = 352) |
Автор: Akina 12.07.23, 17:46 |
Не, фигня получится - на показанных данных такой запрос вернёт ещё и ProductID=4, у которого AttrId = 8 имеет значение AttrValueId = 331. |
Автор: Majestio 12.07.23, 19:57 |
Цитата Akina @ Не, фигня получится - на показанных данных такой запрос вернёт ещё и ProductID=4, у которого AttrId = 8 имеет значение AttrValueId = 331. Согласен. Я невнимательно прочел условие. Тогда альтернативный вариант запроса: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> SELECT A.ProductId FROM ProductTable AS A LEFT JOIN ProductTable AS B ON A.ProductId = B.ProductId WHERE (A.AttrId = 5 AND A.AttrValueId = 1010) AND (B.AttrId = 8 AND B.AttrValueId = 352) Какой из запросов будет лучше - я без понятия. |
Автор: Костик+ 18.07.23, 14:06 |
Простите за отложенный ответ. Majestio, Akina, спасибо вам, что уделили время и помогли мне. Вот примерно такой синтаксис я и искал, в своей практике не встреч. Но, загуглив, нашёл ключевые слова для поиска "WHERE IS multicolumn". Буду читать, разбираться. Попробовал на MSSQL - ругается, мол такой синтаксис не понимает. Попробую ещё на MySQL/MariaDB для сравнения, проверю и отпишу чуть позже. Ещё раз, всем - спасибо! |
Автор: Akina 18.07.23, 18:23 |
Если гуглить - то по термину "логическое деление".. |