![>](style_images/1/nav_m.gif)
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.137.177.241] |
![]() |
|
![]() | Данный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ. |
Сообщ.
#1
,
|
|
|
Доброго времени суток, всем!
Собственно, сабж. Есть таблица вида: ![]() ![]() 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 Т.е., получается что-то типа такого: ![]() ![]() SELECT ProductID FROM ProductTable WHERE (AttrId = 5 AND AttrValueId = 1010) AND (AttrId = 8 AND AttrValueId = 352) В результате выполнения подобного запроса для таблицы из примера выше, получим выборку: ![]() ![]() ProductId ---------- 1 3 ProductId 2 и 4 не подойдут, т.к. для них выполняется только одно из условий. БД: MSSQL. Надеюсь, правильно сформулировал свою мысль. |
Сообщ.
#2
,
|
|
|
Цитата Костик+ @ Каждый ProductId может иметь только один AttrId. В таблице ProductId = 1 имеет пять AttrId ... дальше не читал ![]() |
![]() |
Сообщ.
#3
,
|
|
![]() ![]() SELECT ProductID FROM ProductTable WHERE ( AttrId, AttrValueId ) IN ( (5, 1010), (8, 352) ) GROUP BY ProductID HAVING COUNT( /* DISTINCT */ AttrId ) = 2 |
Сообщ.
#4
,
|
|
|
Цитата Majestio @ В таблице ProductId = 1 имеет пять AttrId ... дальше не читал Да, спасибо. Резонное замечание. Прошу прощения, с утра не выспался. Имеется ввиду, что параметр AttrId уникален для каждого ProductId. Т.е. ситуация: ![]() ![]() ProductId | AttrId ----------+-------- 1 |5 1 |6 1 |7 //... может быть, а: ![]() ![]() ProductId | AttrId ----------+-------- 1 |4 1 |4 1 |4 не может. |
Сообщ.
#5
,
|
|
|
Цитата Костик+ @ Т.е., получается что-то типа такого: ![]() ![]() SELECT ProductID FROM ProductTable WHERE (AttrId = 5 AND AttrValueId = 1010) OR -- <--- тут (AttrId = 8 AND AttrValueId = 352) |
![]() |
Сообщ.
#6
,
|
|
Цитата Majestio @ В операторе WHERE собирай условия не по "и", а по "или", и всё получится Не, фигня получится - на показанных данных такой запрос вернёт ещё и ProductID=4, у которого AttrId = 8 имеет значение AttrValueId = 331. |
Сообщ.
#7
,
|
|
|
Цитата Akina @ Не, фигня получится - на показанных данных такой запрос вернёт ещё и ProductID=4, у которого AttrId = 8 имеет значение AttrValueId = 331. Согласен. Я невнимательно прочел условие. Тогда альтернативный вариант запроса: ![]() ![]() 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) Какой из запросов будет лучше - я без понятия. |
Сообщ.
#8
,
|
|
|
Простите за отложенный ответ. Majestio, Akina, спасибо вам, что уделили время и помогли мне.
Вот примерно такой синтаксис я и искал, в своей практике не встреч. Но, загуглив, нашёл ключевые слова для поиска "WHERE IS multicolumn". Буду читать, разбираться. Попробовал на MSSQL - ругается, мол такой синтаксис не понимает. Попробую ещё на MySQL/MariaDB для сравнения, проверю и отпишу чуть позже. Ещё раз, всем - спасибо! |
![]() |
Сообщ.
#9
,
|
|
Если гуглить - то по термину "логическое деление"..
|