我有一个查询,我需要获取名称& 销售中涉及的每个销售员的编号(ID)。
SELECT
S.SaleID,
P.PersonID,
P.Name
FROM Sale S
LEFT JOIN PersonSales PS ON PS.SaleID = S.SaleID
LEFT JOIN Person P ON P.PersonID = PS.PersonID
但我必须把它作为列显示:
SELECT * FROM (
SELECT
S.SaleID,
P.PersonID,
P.Name,
// - This will give me numbers 1+ for each Sale, per Person
DENSE_RANK() OVER (PARTITION BY S.SaleID OVER P.PersonID) AS [Person#]
FROM Sale S
LEFT JOIN PersonSales PS ON PS.SaleID = S.SaleID
LEFT JOIN Person P ON P.PersonID = PS.PersonID
) AS Q
PIVOT (
AGGREGATE(?) FOR [Person#] IN ([1], [2], [3], [4], [5])
) AS P
我的问题是,如果Name
和PersonID
不是聚合,而是枢轴中的这两个值,我该如何获得它?
像这样:
SaleID Name ID Name ID
1 Seller A 1 Seller B 2
2 Seller C 3
3 Seller A 1 Seller C 3
答案 0 :(得分:1)
从我最近注意到的情况来看,case
使用aggregates(min or max)
的效果优于pivot
,但不是很漂亮。
SELECT SaleID,
MAX(CASE WHEN [Person#] = 1 THEN NAME END) AS [Name],
MAX(CASE WHEN [Person#] = 1 THEN PersonID END) AS [ID],
MAX(CASE WHEN [Person#] = 2 THEN NAME END) AS [Name],
MAX(CASE WHEN [Person#] = 2 THEN PersonID END) AS [ID],
MAX(CASE WHEN [Person#] = 3 THEN NAME END) AS [Name],
MAX(CASE WHEN [Person#] = 3 THEN PersonID END) AS [ID],
MAX(CASE WHEN [Person#] = 4 THEN NAME END) AS [Name],
MAX(CASE WHEN [Person#] = 4 THEN PersonID END) AS [ID],
MAX(CASE WHEN [Person#] = 5 THEN NAME END) AS [Name],
MAX(CASE WHEN [Person#] = 5 THEN PersonID END) AS [ID]
FROM (SELECT S.SaleID,
P.PersonID,
P.Name,
DENSE_RANK() OVER (PARTITION BY S.SaleID ORDER BY P.PersonID) AS [Person#]
FROM Sale S
LEFT JOIN PersonSales PS ON PS.SaleID = S.SaleID
LEFT JOIN Person P ON P.PersonID = PS.PersonID
) t
GROUP BY SaleID
使用更多聚合和更多旋转,您也可以使用。
SELECT SaleId,
MAX(Name1) [Name], MAX(Id1) [Id],
MAX(Name2) [Name], MAX(Id2) [Id],
MAX(Name3) [Name], MAX(Id3) [Id],
MAX(Name4) [Name], MAX(Id4) [Id],
MAX(Name5) [Name], MAX(Id5) [Id]
FROM (SELECT S.SaleID,
P.PersonID,
P.Name,
CONCAT('Name',DENSE_RANK() OVER (PARTITION BY S.SaleID ORDER BY P.PersonID)) AS [Person#],
CONCAT('Id',DENSE_RANK() OVER (PARTITION BY S.SaleID ORDER BY P.PersonID)) AS [PersonID#]
FROM Sale S
LEFT JOIN PersonSales PS ON PS.SaleID = S.SaleID
LEFT JOIN Person P ON P.PersonID = PS.PersonID
) AS Q
PIVOT ( MAX([Name]) FOR [Person#] IN ([Name1],[Name2],[Name3],[Name4],[Name5]) ) AS P1
PIVOT ( MAX([PersonID]) FOR [PersonID#] IN ([Id1],[Id2],[Id3],[Id4],[Id5]) ) AS P2
GROUP BY [SaleId]
答案 1 :(得分:0)
如果您可以连接ID和名称,这将是一种方式:
DECLARE @Person TABLE(ID INT, Name VARCHAR(100));
INSERT INTO @Person VALUES(1,'Seller A'),(2,'Seller B'),(3,'Seller C');
DECLARE @Sales TABLE(ID INT,PersonID INT);
INSERT INTO @Sales VALUES
(1,1)
,(1,2)
,(2,3)
,(3,1)
,(3,3);
SELECT pvt.*
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY S.ID ORDER BY P.ID) AS Inx
,S.ID AS SaleID
,P.Name + ' (' + CAST(P.ID AS VARCHAR(10)) + ')' AS Name
FROM @Sales AS S
INNER JOIN @Person AS P ON S.PersonID=P.ID
) AS tbl
PIVOT
(
MIN(Name) FOR Inx IN([1],[2],[3])
) AS pvt
如果您不想要连接ID和名称,这是一个诀窍:诀窍是做连接它,但让它看起来像XML 。这之后您可以轻松拆分(typesafe!)。
SELECT pvt.SaleID
,CAST(pvt.[1] AS XML).value('/x[1]','varchar(max)') AS Person_1
,CAST(pvt.[1] AS XML).value('/x[2]','int') AS PersonID_1
,CAST(pvt.[2] AS XML).value('/x[1]','varchar(max)') AS Person_2
,CAST(pvt.[2] AS XML).value('/x[2]','int') AS PersonID_2
,CAST(pvt.[3] AS XML).value('/x[1]','varchar(max)') AS Person_3
,CAST(pvt.[3] AS XML).value('/x[2]','int') AS PersonID_3
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY S.ID ORDER BY P.ID) AS Inx
,S.ID AS SaleID
,'<x>' + P.Name + '</x><x>' + CAST(P.ID AS VARCHAR(10)) + '</x>' AS NameAsXml
FROM @Sales AS S
INNER JOIN @Person AS P ON S.PersonID=P.ID
) AS tbl
PIVOT
(
MIN(NameAsXml) FOR Inx IN([1],[2],[3])
) AS pvt