Sql server 需要关于PIVOT是否是SQL Server中的正确工具的建议吗
我的数据如下所示:Sql server 需要关于PIVOT是否是SQL Server中的正确工具的建议吗,sql-server,sql-server-2008-r2,pivot,row-number,Sql Server,Sql Server 2008 R2,Pivot,Row Number,我的数据如下所示: | ACCNT | AMOUNT | TYPE | YEAR | |-------|--------|------|------| | 458 | 168.80 | A | 2014 | | 458 | 282.77 | A | 2015 | | 458 | 64.70 | B | 2015 | | 458 | 91.25 | A | 2016 | | 458 | 398.00 | B | 2016 | | 458 |
| ACCNT | AMOUNT | TYPE | YEAR |
|-------|--------|------|------|
| 458 | 168.80 | A | 2014 |
| 458 | 282.77 | A | 2015 |
| 458 | 64.70 | B | 2015 |
| 458 | 91.25 | A | 2016 |
| 458 | 398.00 | B | 2016 |
| 458 | 104.45 | C | 2016 |
| 927 | 445.00 | B | 2014 |
| 927 | 25.00 | A | 2015 |
| 927 | 10.00 | NULL | 2015 |
| 927 | 132.00 | A | 2016 |
| 927 | 381.40 | B | 2016 |
| 927 | 210.00 | C | 2016 |
...
| ACCNT | 2014 | 2015 | 2016 |
|-------|-----------|--------------------|----------------------------|
| 458 | 168.80,A | 282.77,A;64.70,B | 91.25,A;398.00,B;104.45,C |
| 927 | 445.00,B | 25.00,A;10.00,NULL | 132.00,A;381.40,B;210.00,C |
...
Accnt可能没有每年的值,并且类型偶尔为空。
我希望每个账户只有一行,并将金额和类型列合并到一个年度标题下,即使其看起来像这样:
| ACCNT | AMOUNT | TYPE | YEAR |
|-------|--------|------|------|
| 458 | 168.80 | A | 2014 |
| 458 | 282.77 | A | 2015 |
| 458 | 64.70 | B | 2015 |
| 458 | 91.25 | A | 2016 |
| 458 | 398.00 | B | 2016 |
| 458 | 104.45 | C | 2016 |
| 927 | 445.00 | B | 2014 |
| 927 | 25.00 | A | 2015 |
| 927 | 10.00 | NULL | 2015 |
| 927 | 132.00 | A | 2016 |
| 927 | 381.40 | B | 2016 |
| 927 | 210.00 | C | 2016 |
...
| ACCNT | 2014 | 2015 | 2016 |
|-------|-----------|--------------------|----------------------------|
| 458 | 168.80,A | 282.77,A;64.70,B | 91.25,A;398.00,B;104.45,C |
| 927 | 445.00,B | 25.00,A;10.00,NULL | 132.00,A;381.40,B;210.00,C |
...
我可以把重点放在[年]
SELECT * FROM
(SELECT [Accnt], [Amount], [Type], [Year] FROM data_table)
AS Source
PIVOT
(
MAX([Amount]) FOR [Year] IN ([2014],[2015],[2016])
) AS PVT
…但每个帐户仍有多行
下面的内容更接近我想要的格式
SELECT Accnt, [1] AS '2014', [2] AS '2015', [3] AS '2016'
FROM (SELECT ROW_NUMBER() OVER (PARTITION BY Accnt ORDER BY [Year] Asc) AS AccountID,
Accnt, CONVERT(nvarchar,Amount) + ',' + [Type] AS Amount_And_Type
FROM data_table) PIVOT (MAX(Amount_And_Type)
FOR AccountID IN ([1], [2], [3])) AS data_pvt
…但它只是给我每个帐户的前三行:
| ACCNT | 2014 | 2015 | 2016 |
|-------|-----------|----------|---------|
| 458 | 168.80,A | 282.77,A | 67.40,B |
| 927 | 445.00,B | 25.00,A | NULL |
我想用支点做的事可能吗 您可以按如下方式查询:
;with cte as (
select Accnt, iif([2014] is null,null, concat([2014],',',[Type])) as [2014a]
,iif([2015] is null,null, concat([2015],',',[Type])) as [2015a]
,iif([2016] is null,null, concat([2016],',',[Type])) as [2016a]
from youracct
pivot(max(amount) for [year] in ([2014],[2015],[2016])) p
)
select c.Accnt, [2014]= stuff(( Select ';'+[2014a] from cte where Accnt = c.Accnt for xml path('')),1,1,'')
,[2015]=stuff(( Select ';'+[2015a] from cte where Accnt = c.Accnt for xml path('')),1,1,'')
,[2016]=stuff(( Select ';'+[2016a] from cte where Accnt = c.Accnt for xml path('')),1,1,'')
from cte c
group by c.Accnt
但这种方法的动态sql有点复杂,但我们可以做到
输出如下:
+-------+---------+-----------------+------------------------+
| Accnt | 2014 | 2015 | 2016 |
+-------+---------+-----------------+------------------------+
| 458 | 168.8,A | 282.77,A;64.7,B | 91.25,A;398,B;104.45,C |
| 927 | 445,B | 10,;25,A | 132,A;381.4,B;210,C |
+-------+---------+-----------------+------------------------+
理想情况下,数据的表示将在表示层处理;不在数据层。这就是为什么数据库有一个pivot呢?看看xml的
stuff
和函数,它们用于将数据行转换为单个字段。iif
和concat
在SQL Server 2008 R2中不起作用,所以我尝试了以下方法:选择Accnt,case[2014]when NULL然后选择'NULL'else(CONVERT(nvarchar,[2014]+','+[类型])结束于[2014a],…
但它将10.00的金额保留为NULL类型。我对该查询如何工作的理解还不足以解释为什么会发生这种情况。对于iif,您可以使用coalesce,而不是concat,您可以使用+让我试着解释一下……如果您单独查询CTE,它将获得一年的pivot,并且这些内容用于连接通过在CTE下方添加select*from CTE单独运行CTE,您将获得输入