我正在使用SQL Server 2012&我有两张桌子。
tblStocks tblFunds
fundCode nvarchar fundCode nvarchar
stockID nvarchar fundType nvarchar
shares int
我将在解释之前展示以下数据的示例,因为它可能更容易首先看到示例。
tblStocks
fundCode stockID shares
abcd m33 20
abcd b22 10
abcd c33 5
abcd p99 6
xyzu m33 10
xyzu b22 8
xyzu w88 12
tblFunds
fundCode fundType
abcd EQ
xyzu EQ
所以请注意,tblStocks的资金可以拥有多只股票,但每只股票在该基金中都是独一无二的,即abcd不会持有两只m33股票。
另请注意abcd和xyzu可以持有相同的股票,因此两者都可以持有m33。
以下是我希望看到的结果。所以我有一个独特的股票清单,然后对于每个基金我都拥有该基金的股票数量。所以我知道我需要在这里使用一个支点(这是我知道的唯一方法)。然而,增加的复杂性(对我而言)是不同基金的数量并不总是两个,所以我不知道如何在sql server中编码?
stockID abcd xyzu
m33 20 10
b22 10 8
c33 5 0
p99 6 0
w88 0 12
答案 0 :(得分:3)
您需要使用动态SQL来创建pivot语句。
类似的东西:
DECLARE @SQL varchar(MAX)
DECLARE @columns varchar(MAX)
SET @columns = 'column1, column2, column3' -- etc.
SET @SQL = 'SELECT * FROM () PIVOT (
' + @columns + '
)'
EXECUTE(@SQL)
因此,您需要获取列(确保没有NULL值)
DECLARE @columns varchar(MAX)
SELECT @columns = COALESCE(@columns + ', ', '') + QUOTENAME(fundCode)
FROM tblFunds
WHERE fundCode IS NOT NULL
PRINT @columns
然后像这样完成查询:
DECLARE @SQL nvarchar(MAX)
DECLARE @columns nvarchar(MAX)
DECLARE @columnsOrder nvarchar(MAX)
SELECT @columns = COALESCE(@columns + N', ', N'') + QUOTENAME(fundCode)
FROM tblFunds
SELECT @columnsOrder = COALESCE(@columnsOrder + N', ', N'') + QUOTENAME(fundCode) + N' DESC'
FROM tblFunds
SET @SQL = N'
SELECT * FROM
(
SELECT
stockid
,fundCode
,shares
FROM tblStocks
) AS dataToPivot
PIVOT
(
SUM(shares)
FOR fundCode IN (' + @columns + N')
) AS p
ORDER BY ' + @columnsOrder + N'
'
-- PRINT @columns
-- PRINT @columnsOrder
-- PRINT @SQL
EXECUTE(@SQL)
你仍然应该抓住tblFunds中没有条目的情况(在一开始,查询运行正常,但不返回任何值,也没有空表)...
我还会创建另外两个测试条目,一个用撇号,另一个用方括号[]
INSERT INTO tblFunds (fundCode, fundType) VALUES (N'ACME [US]', N'EQ');
INSERT INTO tblFunds (fundCode, fundType) VALUES (N'Goa''uld Charity Fund', N'EQ');
当你在列名上运行QUOTENAME时,你会发现它的工作正常。