-- Создаем таблицы
-- Таблица товаров
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)
-- Создаем таблицы
CREATE TABLE T1 (id INT IDENTITY(1,1),item1 int,item2 int,item3 INT)
CREATE TABLE T2 (id INT IDENTITY(1,1),item_id INT, itype VARCHAR(10) )
-- Наполняем данными
-- Таблица T1
INSERT INTO [dbo].[T1] ([item1],[item2],[item3])VALUES(11,12,13)
INSERT INTO [dbo].[T1] ([item1],[item2],[item3])VALUES(21,22,23)
INSERT INTO [dbo].[T1] ([item1],[item2],[item3])VALUES(31,32,33)
INSERT INTO [dbo].[T1] ([item1],[item2],[item3])VALUES(41,42,43)
INSERT INTO [dbo].[T1] ([item1],[item2],[item3])VALUES(51,52,53)
INSERT INTO [dbo].[T1] ([item1],[item2],[item3])VALUES(11,32,53)
INSERT INTO [dbo].[T1] ([item1],[item2],[item3])VALUES(17,32,53)
-- Таблица T2
INSERT INTO [dbo].[T2]([item_id],[itype]) VALUES(21,'A')
INSERT INTO [dbo].[T2]([item_id],[itype]) VALUES(11,'B')
INSERT INTO [dbo].[T2]([item_id],[itype]) VALUES(13,'B')
INSERT INTO [dbo].[T2]([item_id],[itype]) VALUES(41,'A')
INSERT INTO [dbo].[T2]([item_id],[itype]) VALUES(42,'A')
INSERT INTO [dbo].[T2]([item_id],[itype]) VALUES(43,'A')
INSERT INTO [dbo].[T2]([item_id],[itype]) VALUES(17,'A')
-- Исходный запрос
SELECT * FROM T1 WHERE
T1.item1 IN (SELECT item_id FROM T2 WHERE itype='A') AND
T1.item2 IN (SELECT item_id FROM T2 WHERE itype='A') AND
T1.item3 IN (SELECT item_id FROM T2 WHERE itype='A')
-- Запрос с одним джойном
;WITH CTE_OneSubQuery
AS
(
SELECT DISTINCT
tt1.id, tt1.item1,tt1.item2,tt1.item3
,CASE (COUNT (tt2.item_id) OVER (PARTITION BY tt1.id)) WHEN 3 THEN 1 END AS [kol]
FROM T1 tt1
JOIN t2 tt2 ON tt2.item_id =CASE
WHEN tt2.item_id = tt1.item1 THEN tt1.item1
WHEN tt2.item_id = tt1.item2 THEN tt1.item2
WHEN tt2.item_id = tt1.item3 THEN tt1.item3
END
WHERE tt2.itype = 'A'
)
SELECT id, item1,item2,item3 FROM CTE_OneSubQuery
WHERE kol =1
В таких случаях рекомендую делать так :)
Не самое кошерное решение - но зато понятно что происходит и минимум возможности для ошибки :)
--пример таблиц
CREATE TABLE uzer1 (id INT, name1 NVARCHAR(20))
CREATE TABLE uzer2 (id INT, name2 NVARCHAR(20))
-- Заполняем данными
-- Таблица [uzer1]
INSERT INTO [dbo].[uzer1]([id],[name1]) VALUES(1,'Вася')
INSERT INTO [dbo].[uzer1]([id],[name1]) VALUES(2,'Петя')
INSERT INTO [dbo].[uzer1]([id],[name1]) VALUES(3,'Гундяев')
-- Таблица [uzer2]
INSERT INTO [dbo].[uzer2]([id],[name2]) VALUES(1,'Вася')
INSERT INTO [dbo].[uzer2]([id],[name2]) VALUES(3,'Кирил')
--Шаг 1
-- Пишем CTE с джойном двух таблиц - Для проверки что именно у нас на что заменится
;WITH cte_Update
as
(SELECT t1.Name1 AS 'Вот это'
, t2.Name2 AS 'апдейтим на это'
FROM [uzer1] t1
JOIN [uzer2] t2 ON t1.id=t2.id)
--Проверяем что у нас проапдетится именно то что нам надо
SELECT * FROM cte_Update
--Шаг 2
-- пишем все тоже самое только вместо селекта Апдейт
;wITH cte_Update
as
(SELECT t1.Name1 AS 'Вот это'
, t2.Name2 AS 'апдейтим на это'
FROM [uzer1] t1
JOIN [uzer2] t2 ON t1.id=t2.id)
--Апдейтим
UPDATE cte_Update
SET [Вот это] =[апдейтим на это]
-- я использую такой способ, мне он кажется более безопасным и быстрым в написании :)
-- Делаем таблички
CREATE TABLE story( id int ,[text] text,author_id int )
CREATE TABLE story_comments( id int,s_id INT,[text] text)
-- Заполнем данными
TRUNCATE TABLE [story]
TRUNCATE TABLE [story_comments]
INSERT INTO [dbo].[story]([id],[text],[author_id])VALUES(1,'Статья 1',1)
INSERT INTO [dbo].[story]([id],[text],[author_id])VALUES(2,'Статья 2',2)
INSERT INTO [dbo].[story_comments]([id],[s_id],[text])VALUES(1,1,'Первый комент Первой статьи')
INSERT INTO [dbo].[story_comments]([id],[s_id],[text])VALUES(2,1,'Второй комент Первой статьи')
INSERT INTO [dbo].[story_comments]([id],[s_id],[text])VALUES(3,1,'Третий комент Первой статьи')
-- Сам запрос
;WITH cte
AS
(
SELECT [text2]=
(
SELECT
--s.id AS 'Story_ID',
s.[text] AS 'Story_Text'
,
(
SELECT ISNULL(
REPLACE(
REPLACE(
REPLACE(
(SELECT [text]=
(SELECT sc.[text]AS 'comment_Text'
FROM [story_comments] sc
WHERE s.id=sc.[s_id]
FOR XML PATH (''))),'</comment_Text><comment_Text>',',')
,'<comment_Text>','['),'</comment_Text>',']')
,'[NULL]')
)
FROM [story] s
FOR XML PATH('')
))
SELECT '['+
REPLACE(
replace (
REPLACE (text2,'<Story_Text>','[')
,'</Story_Text>[',',[')
,'][','],[')+']'
FROM cte
Ответ:
[[Статья 1,[Первый комент Первой статьи,Второй комент Первой статьи,Третий комент Первой статьи],[Статья 2,[NULL]]