我知道这个主题无处不在,但我无法让它正常工作。它可能非常简单。
以下是基本查询后的数据示例:
-----------------------------------
|Site| Model | Count |
-----------------------------------
AAA ProLiant DL380 G7 1
AAA OptiPlex 790 500
BBB OptiPlex 780 80
CCC OptiPlex 790 23
...
我想要的是列名称是动态的:
--------------------------------------------------------
|Site| ProLiant DL380 G7 | OptiPlex 790 | OptiPlex 780 |...
--------------------------------------------------------
AAA 1 500 0
BBB 0 0 80
CCC 0 23 0
根据我的研究,这是我迄今为止编写的代码:
DECLARE
@cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
SELECT @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(Model)
FROM
(
SELECT IIF(COMP.Manufacturer0 LIKE '%lenovo%',PRD.Version0,COMP.Model0) AS Model
FROM v_GS_COMPUTER_SYSTEM COMP
JOIN v_GS_COMPUTER_SYSTEM_PRODUCT PRD ON COMP.ResourceID=PRD.ResourceID
) AS inner_tbl
FOR XML PATH(''),Type).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET @query = 'SELECT Site, ' + @cols + ' FROM
(
SELECT Site, Model, COUNT(Model) AS Count FROM
(
SELECT UPPER(Substring(SYS.Name0,2,3)) AS Site, IIF(COMP.Manufacturer0 LIKE ''%lenovo%'',PRD.Version0,COMP.Model0) AS Model
FROM v_GS_System SYS
JOIN v_GS_COMPUTER_SYSTEM COMP ON SYS.ResourceID=COMP.ResourceID
JOIN v_GS_COMPUTER_SYSTEM_PRODUCT PRD ON SYS.ResourceID=PRD.ResourceID
) AS inner_tbl2
GROUP BY Site, Model
) AS inner_tbl1
PIVOT
(
max(Model)
FOR Site in ' + @cols + ')
) AS piv
'
EXECUTE(@query)
当我运行查询时,出现语法错误。
答案 0 :(得分:3)
使用Dynamic Sql
IF OBJECT_ID('tempdb..#TempData', 'U') IS NOT NULL
DROP TABLE #TempData;
CREATE TABLE #TempData (
[Site] CHAR(3) NOT NULL,
Model VARCHAR(30) NOT NULL,
SomeCount INT NOT NULL DEFAULT(0)
);
INSERT #TempData (Site, Model, SomeCount) VALUES
('AAA', 'ProLiant DL380 G7', 1),
('AAA', 'OptiPlex 790', 500),
('BBB', 'OptiPlex 780', 80),
('CCC', 'OptiPlex 790', 23);
Declare @DynamicCol nvarchar(max),@DynamicColNull nvarchar(max)
,@Sql nvarchar(max)
SELECT @DynamicColNull=STUFF((SELECT DISTINCT ', '+'ISNULL('+QUOTENAME(Model),','+'''0'''+') As '+QUOTENAME(Model)
FROM #TempData FOR XML PATH ('')),1,2,'')
SELECT @DynamicCol=STUFF((SELECT DISTINCT ', '+QUOTENAME(Model) FROM #TempData FOR XML PATH ('')),1,2,'')
SET @Sql='SELECT [Site], '+@DynamicColNull+' From
(
SELECT * from #TempData
)
AS Src
PIVOT
(
MAX(SomeCount) FOR [Model] IN ('+@DynamicCol+')
)AS Pvt'
PRINT @Sql
EXEC(@Sql)
结果
Site OptiPlex 780 OptiPlex 790 ProLiant DL380 G7
AAA 0 500 1
BBB 80 0 0
CCC 0 23 0
答案 1 :(得分:0)
试一试......
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
CREATE TABLE #TestData (
[Site] CHAR(3) NOT NULL,
Model VARCHAR(30) NOT NULL,
SomeCount INT NOT NULL DEFAULT(0)
);
INSERT #TestData (Site, Model, SomeCount) VALUES
('AAA', 'ProLiant DL380 G7', 1),
('AAA', 'OptiPlex 790', 500),
('BBB', 'OptiPlex 780', 80),
('CCC', 'OptiPlex 790', 23);
--==========================================================
DECLARE
@PivotColumns NVARCHAR(4000),
@sql NVARCHAR(4000),
@DeBug BIT = 0;
SELECT
@PivotColumns = CONCAT(@PivotColumns, N',
', QUOTENAME(td.Model), N' = SUM(CASE WHEN td.Model = ', QUOTENAME(td.Model, ''''), N' THEN td.SomeCount END)')
FROM
#TestData td
GROUP BY
td.Model
-- ORDER BY ??? if you want the columns in a specific ordinal position.
;
SET @sql = CONCAT(N'
SELECT
td.[Site]',
@PivotColumns, N'
FROM
#TestData td
GROUP BY
td.[Site];');
IF @DeBug = 1
BEGIN
PRINT (@sql);
END;
ELSE
BEGIN
EXEC sys.sp_executesql @sql;
END;
结果...
Site OptiPlex 780 OptiPlex 790 ProLiant DL380 G7
---- ------------ ------------ -----------------
AAA NULL 500 1
BBB 80 NULL NULL
CCC NULL 23 NULL
答案 2 :(得分:0)
从您的查询
PIVOT
(
max(Model)
FOR Site in ' + @cols + ')
) AS piv
您应该使用Count
函数中的MAX()
列和Model
部分中的FOR...IN
列。这是因为您的新值将是Count
,而您的新列将来自Model