librown
@librown
На-все-руки-мастер и немного кодер

Как выбрать «товары» содержащие одновременно несколько «параметров»?

Привет!
Есть товары (таблица "article") и их параметры (таблица "article_param").
Каждый товар может содержать от 1 до X параметров.

Привязку параметров к товарам храню в третьей таблице "article_param_item" (id, id_article, id_param).

Выбрать все товары содержащие один параметр - легко:
SELECT * FROM article AS a, article_param_item AS api 
WHERE a.id = api.id_article AND api.id=15 
GROUP BY a.id

Но как выбрать товары одновременно удовлетворяющим характеристикам id_param=15 и id_param=16 ?
  • Вопрос задан
  • 115 просмотров
Пригласить эксперта
Ответы на вопрос 2
@dmitryKovalskiy
программист средней руки
Самое простое - заменить AND api.id=15 на AND api.id IN (список нужных id)
Ответ написан
igruschkafox
@igruschkafox
Специалист по сопровождению БД MS SQL
Примерно так (с точки зрения оптимизации стоит еще подумать но принцип рабочий)
-- Создаем таблицы
-- Таблица товаров
Create table article (
id_article int identity(1,1),
Name_article NVarchar(20))

-- Таблица парметров 
Create table article_param (
id_param int identity(1,1),
Name_param Nvarchar (100))

-- Таблица соотношения
CREATE TABLE dbo.article_param_item
(
  id int identity(1,1),
   id_article  int not NULL,
   id_param  int not NULL
)


 truncate table article
 truncate table article_param
 truncate table article_param_item


-- Заполняем таблицы данным для примера
INSERT INTO [dbo].[article] (Name_article) VALUES (N'Утюг')
INSERT INTO [dbo].[article] (Name_article) VALUES (N'Стол')
INSERT INTO [dbo].[article] (Name_article) VALUES (N'Телевизор')

INSERT INTO [dbo].[article_param](Name_param)VALUES (N'Пластиковый')
INSERT INTO [dbo].[article_param](Name_param)VALUES (N'Плоский')
INSERT INTO [dbo].[article_param](Name_param)VALUES (N'Красный')
INSERT INTO [dbo].[article_param](Name_param)VALUES (N'Бракованный')
INSERT INTO [dbo].[article_param](Name_param)VALUES (N'Новый')

-- Заполняем таблицу соотношений
INSERT INTO [dbo].[article_param_item]([id_article],[id_param])VALUES(1,1) -- Утюг Пластиковый
INSERT INTO [dbo].[article_param_item]([id_article],[id_param])VALUES(1,5) -- Утюг Новый

INSERT INTO [dbo].[article_param_item]([id_article],[id_param])VALUES(2,1) -- Стол Пластиковый
INSERT INTO [dbo].[article_param_item]([id_article],[id_param])VALUES(2,2) -- Стол Плоский
INSERT INTO [dbo].[article_param_item]([id_article],[id_param])VALUES(2,3) -- Стол Бракованный
INSERT INTO [dbo].[article_param_item]([id_article],[id_param])VALUES(2,4) -- Стол Красный

INSERT INTO [dbo].[article_param_item]([id_article],[id_param])VALUES(3,2) -- Телевизор Плоский
INSERT INTO [dbo].[article_param_item]([id_article],[id_param])VALUES(3,5) -- Телевизор Новый


-- Отображаем все товары с их параметрами
SELECT *
  FROM [dbo].[article] art 
  join [article_param_item] rel on art.id_article=rel.id_article
  join [article_param] parametr on parametr.id_param =rel.id_param

-- Для поиска по нескольким параметрам поиска необходимо занести их во временную таблицу
Create table ##Param_table (id_parm int)

-- Допустим ищем товары удовлетворяющие двум параметрам
-- Плоский и Новый
insert into  ##Param_table (id_parm) values (2)
insert into  ##Param_table (id_parm) values (5)

-- Находим все товары удовлетворяющие нашему списку параметров

;with CTE_ArticleInParam as
(
SELECT art.[Name_article],parametr.Name_param
,count (parametr.Name_param) over (partition by art.[Name_article]) as 'Count_Param'
FROM [dbo].[article] art 
join [article_param_item] rel on art.id_article=rel.id_article 
join [article_param] parametr on parametr.id_param =rel.id_param 
join ##Param_table ParTabl on ParTabl.id_parm = rel.id_param 
)

select [Name_article],Name_param,Count_Param
from CTE_ArticleInParam
where Count_Param = (select count (*) from ##Param_table)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы