如何对varchar类型的列使用pivot

时间:2017-08-08 05:48:27

标签: sql sql-server-2008-r2 pivot

我的表是:

SBType|SBName|Qty
===================
SMDB    SB01    1
SMDB    SB01    4
SMDB    SB02    2
SMDB    SB02    5
SMDB    SB03    3
SMDB    SB03    6

我想要的输出是:

SB01 | SB02 | SB03
==================
1       2       3 
4       5       6

这就是我的代码:

SELECT *
FROM (
SELECT 
    SM.SBName,ISNULL(ES.Qty,0)Qty
FROM RE_ES_SwitchBoard_Mast SM
left outer join RE_ES_Estimations ES on SM.PrCode=ES.PrCode and 
Sm.SBType=ES.SBType and SM.SBName=ES.SBName 
 Where SM.PrCode='PR004' and SM.SBType='SMDB'
) as s
PIVOT
(
Max(Qty)
FOR [SBName] IN (SB01, SB02, SB03)
)AS pvthere

我尝试的结果如下:

SB01    SB02    SB03
  1     2       3

我尝试过MAX(Qty),但它没有用。 提前谢谢。

2 个答案:

答案 0 :(得分:0)

动态查询是在pivot中使用varchar列的唯一方法。看看下面的代码来了解它。

第一步是为您需要在数据透视中使用的列生成以逗号分隔的项目列表。

然后,您可以在动态查询中使用此生成的列表来进行数据透视列。

注意:例如,我使用了临时表。将其替换为您的实际表格。

CREATE TABLE  #temptable
(
    SBType VARCHAR(20),
    SBName VARCHAR(20),
    Qty INT
)

INSERT INTO #temptable SELECT 'SMDB','SB01',1
INSERT INTO #temptable SELECT 'SMDB','SB01',4
INSERT INTO #temptable SELECT 'SMDB','SB02',2
INSERT INTO #temptable SELECT 'SMDB','SB02',5
INSERT INTO #temptable SELECT 'SMDB','SB03',3
INSERT INTO #temptable SELECT 'SMDB','SB03',6

SELECT * FROM #temptable

DECLARE @cols AS NVARCHAR(MAX)

SELECT @cols = STUFF((SELECT ',' + QUOTENAME(SBName) 
                    from #temptable
                    group by SBName
                    order by SBName
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

SELECT @cols

DECLARE @query NVARCHAR(MAX)
SET @query = '
SELECT *
FROM 
(
  SELECT SBType,SBName,Qty,
  row_number() over (partition by SBName order by Qty) as rn
  FROM #temptable
) src
PIVOT
(
  MIN(Qty)
  FOR SBName IN (' + @cols + ')
) piv;'

EXEC(@query)

DROP TABLE #temptable

答案 1 :(得分:0)

你快到了。 通过将ROW_NUMBER() OVER (PARTITION BY SBName ORDER BY Qty) rn添加到PIVOT子句的源中,您可以获得不同SBName而不是一个分组行的多行。您的查询应如下所示:

SELECT SB01, SB02, SB03
FROM (
SELECT 
    ROW_NUMBER() OVER (PARTITION BY SB.SBName ORDER BY Qty) rn,
    SB.SBName,ISNULL(ES.Qty,0) Qty
    FROM RE_ES_SwitchBoard_Mast SM
    left outer join RE_ES_Estimations ES on SM.PrCode=ES.PrCode and 
    Sm.SBType=ES.SBType and SM.SBName=ES.SBName 
    Where SM.PrCode='PR004' and SM.SBType='SMDB'
) as s
PIVOT
(
    Max(Qty)
    FOR [SBName] IN (SB01, SB02, SB03)
)AS pvthere

这里有一个可验证的例子:

CREATE TABLE  #sample
(
    SBType varchar(MAX),
    SBName varchar(MAX),
    Qty int
)

INSERT INTO #sample VALUES ('SMDB','SB01',1)
INSERT INTO #sample VALUES ('SMDB','SB01',4)
INSERT INTO #sample VALUES ('SMDB','SB02',2)
INSERT INTO #sample VALUES ('SMDB','SB02',5)
INSERT INTO #sample VALUES ('SMDB','SB03',3)
INSERT INTO #sample VALUES ('SMDB','SB03',6)

SELECT SB01, SB02, SB03
FROM (
SELECT 
    ROW_NUMBER() OVER (PARTITION BY SBName ORDER BY Qty) rn, SBName,ISNULL(Qty,0) Qty
    FROM #sample 
) as s
PIVOT
(
   Max(Qty)
FOR [SBName] IN (SB01, SB02, SB03)
) AS pvthere

DROP TABLE #sample