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

Откуда: Москва
Сообщений: 2646
DECLARE @table TABLE (psa_ProductID INT, psa_AttributeID INT, NAME varchar(20))

INSERT INTO @table values(34,1,'Тест 9')
INSERT INTO @table values(34,2,'Тест 7')
INSERT INTO @table values(34,3,'Тест 3')
INSERT INTO @table values(34,4,'Тест 4')
INSERT INTO @table values(35,5,'Тест 7')
INSERT INTO @table values(35,6,'Тест 5')

SELECT 
    t1.psa_ProductID
    ,t1.NAME as NAME1
    ,t2.NAME as NAME2
    ,t3.NAME as NAME3
FROM
(SELECT 34 A) TT
LEFT JOIN @table t1 ON TT.A = t1.psa_ProductID AND t1.psa_AttributeID =1
LEFT JOIN @table t2 ON TT.A = t2.psa_ProductID AND t2.psa_AttributeID =2
LEFT JOIN @table t3 ON TT.A = t3.psa_ProductID AND t3.psa_AttributeID =3

Как переписать этот запрос через PIVOT, чтобы обращение к таблице @table было одно?
28 авг 12, 15:43    [13076991]     Ответить | Цитировать Сообщить модератору
 Re: Переписать запрос через PIVOT  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
trew,

Можно и без пивота в одно
SELECT 
    t1.psa_ProductID,
    NAME1 = max(case when psa_AttributeID = 1 then NAME end),
    NAME2 = max(case when psa_AttributeID = 2 then NAME end),
    NAME3 = max(case when psa_AttributeID = 3 then NAME end)
FROM
	(SELECT 34 A) TT
	JOIN @table t1 ON TT.A = t1.psa_ProductID
group by
	t1.psa_ProductID
28 авг 12, 15:49    [13077052]     Ответить | Цитировать Сообщить модератору
 Re: Переписать запрос через PIVOT  [new]
qwerty112
Guest
select psa_ProductID, [1] as NAME1, [2] as NAME2, [3] as NAME3
from
(select * from @table where psa_ProductID=34) a
pivot (min(NAME) for psa_AttributeID in ([1],[2],[3])) pvt
28 авг 12, 15:51    [13077062]     Ответить | Цитировать Сообщить модератору
 Re: Переписать запрос через PIVOT  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Кстати, не уверен, важно ли, но подумал что на всякий случай нужно уточнить.
Хоть в вашем примере запросы и дадут одинаковый результат, запросы разные и на других данных могут дать разные результаты.
28 авг 12, 15:52    [13077077]     Ответить | Цитировать Сообщить модератору
 Re: Переписать запрос через PIVOT  [new]
trew
Member

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

Спасибо за PIVOT.
Про CASE думал, но не нравиться что нужно все поля (их много) группировать.

А можно пример, когда на других данных могут дать разные результаты?
28 авг 12, 15:57    [13077130]     Ответить | Цитировать Сообщить модератору
 Re: Переписать запрос через PIVOT  [new]
trew
Member

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

У меня аттрибуты не повторяются для продукта. Поэтому такого как ниже, нет.
DECLARE @table TABLE (psa_ProductID INT, psa_AttributeID INT, NAME varchar(20))

INSERT INTO @table values(34,1,'Тест 9')
INSERT INTO @table values(34,2,'Тест 7')
INSERT INTO @table values(34,2,'Тест 3')
INSERT INTO @table values(34,4,'Тест 4')
INSERT INTO @table values(35,5,'Тест 7')
INSERT INTO @table values(35,6,'Тест 5')

select psa_ProductID, [1] as NAME1, [2] as NAME2, [3] as NAME3
from
(select * from @table where psa_ProductID=34) a
pivot (min(NAME) for psa_AttributeID in ([1],[2],[3])) pvt
28 авг 12, 16:03    [13077176]     Ответить | Цитировать Сообщить модератору
 Re: Переписать запрос через PIVOT  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
trew
SomewhereSomehow,

Спасибо за PIVOT.
Про CASE думал, но не нравиться что нужно все поля (их много) группировать.

А можно пример, когда на других данных могут дать разные результаты?

За пивот спасибо не мне =)
Про группировку, ради интереса, сравните планы пивота и групбай.
А пример:
+
DECLARE @table TABLE (psa_ProductID INT, psa_AttributeID INT, NAME varchar(20))

INSERT INTO @table values(34,1,'Тест 9')
INSERT INTO @table values(34,1,'Тест 8')
INSERT INTO @table values(34,2,'Тест 7')
INSERT INTO @table values(34,3,'Тест 3')
INSERT INTO @table values(34,4,'Тест 4')
INSERT INTO @table values(35,5,'Тест 7')
INSERT INTO @table values(35,6,'Тест 5')

SELECT 
    t1.psa_ProductID
    ,t1.NAME as NAME1
    ,t2.NAME as NAME2
    ,t3.NAME as NAME3
FROM
(SELECT 34 A) TT
LEFT JOIN @table t1 ON TT.A = t1.psa_ProductID AND t1.psa_AttributeID =1
LEFT JOIN @table t2 ON TT.A = t2.psa_ProductID AND t2.psa_AttributeID =2
LEFT JOIN @table t3 ON TT.A = t3.psa_ProductID AND t3.psa_AttributeID =3

SELECT 
    t1.psa_ProductID,
    NAME1 = max(case when psa_AttributeID = 1 then NAME end),
    NAME2 = max(case when psa_AttributeID = 2 then NAME end),
    NAME3 = max(case when psa_AttributeID = 3 then NAME end)
FROM
	(SELECT 34 A) TT
	JOIN @table t1 ON TT.A = t1.psa_ProductID
group by
	t1.psa_ProductID
	
select psa_ProductID, [1] as NAME1, [2] as NAME2, [3] as NAME3
from
(select * from @table where psa_ProductID=34) a
pivot (max(NAME) for psa_AttributeID in ([1],[2],[3])) pvt
28 авг 12, 16:08    [13077208]     Ответить | Цитировать Сообщить модератору
 Re: Переписать запрос через PIVOT  [new]
trew
Member

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

Графический план, в виде значков, одинаковый.
  |--Stream Aggregate(DEFINE:([Expr1004]=MAX([Expr1007]), [Expr1005]=MAX([Expr1008]), [Expr1006]=MAX([Expr1009]), [t1].[psa_ProductID]=ANY(@table.[psa_ProductID] as [t1].[psa_ProductID])))
       |--Compute Scalar(DEFINE:([Expr1007]=CASE WHEN @table.[psa_AttributeID] as [t1].[psa_AttributeID]=(1) THEN @table.[NAME] as [t1].[NAME] ELSE NULL END, [Expr1008]=CASE WHEN @table.[psa_AttributeID] as [t1].[psa_AttributeID]=(2) THEN @table.[NAME] as 
            |--Table Scan(OBJECT:(@table AS [t1]), WHERE:(@table.[psa_ProductID] as [t1].[psa_ProductID]=(34)))
            
            
  |--Stream Aggregate(GROUP BY:([psa_ProductID]) DEFINE:([Expr1007]=MAX(CASE WHEN [psa_AttributeID]=(1) THEN [NAME] ELSE NULL END), [Expr1008]=MAX(CASE WHEN [psa_AttributeID]=(2) THEN [NAME] ELSE NULL END), [Expr1009]=MAX(CASE WHEN [psa_AttributeID]=(3) TH
       |--Compute Scalar(DEFINE:([psa_ProductID]=[psa_ProductID]))
            |--Table Scan(OBJECT:(@table), WHERE:([psa_ProductID]=(34)))  
28 авг 12, 16:20    [13077314]     Ответить | Цитировать Сообщить модератору
 Re: Переписать запрос через PIVOT  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
trew,

Ну видите, агрегация есть и там и там. Вот вам и ответ по поводу "но не нравиться что нужно все поля (их много) группировать".
28 авг 12, 16:48    [13077588]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить