MS SQL Server中的动态数据透视表
我正在尝试在最后两列上做一个动态数据透视表,我从一张表中取出并加入到另一张表的内容中。我需要将名称值转换为标题字段和值的值,以便在下面相应地填写。这是我当前的查询:MS SQL Server中的动态数据透视表
USE Innovate
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT @ColumnName= ISNULL(@ColumnName + ',','')
+ QUOTENAME(NAME)
FROM (SELECT DISTINCT NAME FROM Innovate.dbo.Table1 WHERE Name IS NOT NULL) AS ATTRIBUTE_NAME
WHERE Name LIKE 'Suture_-_2nd_Needle_Code'
OR Name LIKE 'Suture_-_Absorbable'
OR Name LIKE 'Suture_-_Antibacterial'
OR Name LIKE 'Suture_-_Armed'
OR Name LIKE 'Suture_-_Barbed'
OR Name LIKE 'Suture_-_Brand_Name'
OR Name LIKE 'Suture_-_C/R_2nd_Needle_Code'
OR Name LIKE 'Suture_-_C/R_Brand_Name'
OR Name LIKE 'Suture_-_C/R_length'
OR Name LIKE 'Suture_-_C/R_Needle_Code'
OR Name LIKE 'Suture_-_Coating'
OR Name LIKE 'Suture_-_Dyed'
OR Name LIKE 'Suture_-_Filament'
OR Name LIKE 'Suture_-_length_inches'
OR Name LIKE 'Suture_-_Looped'
OR Name LIKE 'Suture_-_Material'
OR Name LIKE 'Suture_-_Needle_Code'
OR Name LIKE 'Suture_-_Needle_Shape'
OR Name LIKE 'Suture_-_Needle_Style'
OR Name LIKE 'Suture_-_Noun'
OR Name LIKE 'Suture_-_pleget'
OR Name LIKE 'Suture_-_Popoff'
OR Name LIKE 'Suture_-_Suture_count'
OR Name LIKE 'Suture_-_Suture_size'
--Prepare the PIVOT query using the dynamic
SET @DynamicPivotQuery =
N'SELECT Table1.Primary_Key, Company_Name, Part_Number, Product_Desc, Innovate_Description, ' + @ColumnName + '
FROM Table1 AS P
LEFT JOIN Table2 AS A ON P.Primary_Key = A.Primary_Key
PIVOT(MAX(A.VALUE)
FOR A.NAME IN (' + @ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXECUTE sp_executesql @DynamicPivotQuery
;
这是我不断收到查询的结果:消息8156, 级别16,状态1,5号线的列“Primary_Key”指定 多次'PVTTable'。消息4104,级别16,状态1,行1 多部分标识符“Table1.Primary_Key”无法绑定。
任何人都可以帮助我转动这些列没有错误信息?我只在代码中指定了Primary_Key,因此我不知道如何多次指定它以及如何解除绑定。
你有一些事情与你的PIVOT声明是有问题的。首先,您试图引用Table1和Table2的表别名,但这些别名在PIVOT的最终选择中不可用。Pivot命令有点像外部选择,并且唯一可用的表别名是枢轴别名。
下一个支点的documenation状态“您可以使用PIVOT和UNPIVOT关系运算符来改变一个表值表达式到另一个表”(https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx)。基本上这意味着你需要一个单一的表格表达式,只有你想要涉及的唯一命名的列被传递给PIVOT命令。后面的部分可能是问题,因为Table1和Table2可能都有一列Primary_Key
,所以pivot不理解引用。
要解决您可以移动您的表1 & 2.加入到内部选择和别名表或建立一个cte并在您的命令中使用cte。这里是前一种方法:
SET @DynamicPivotQuery =
N'SELECT * FROM
(
SELECT Table1.Primary_Key, Company_Name, Part_Number, Product_Desc, Innovate_Description, ' + @ColumnName + '
FROM Table1 AS P
LEFT JOIN Table2 AS A ON P.Primary_Key = A.Primary_Key
) t
PIVOT(MAX(A.VALUE)
FOR NAME IN (' + @ColumnName + ')) AS PVTTable'
马特,它看起来像你建议的查询工作,但我遇到了一个问题,因为在Table1中,所有从Attribute_Name列旋转的新列标题都无法识别(因为它们不存在),所以我一直在这些值的错误,因为它们不在该表中。有没有办法让我从连接中提取这些值以使其能够运行查询? –
你能否用实际错误更新你的文章?如果你的内部查询中缺少值/注释,那么应该让你的数据透视表中的一列为NULL。 – Matt
与下面的脚本尝试..
SET @DynamicPivotQuery =
N'SELECT P.Primary_Key, Company_Name, Part_Number, Product_Desc, Innovate_Description, ' + @ColumnName + '
FROM Table1 AS P
LEFT JOIN Table2 AS A ON P.Primary_Key = A.Primary_Key
PIVOT(MAX(A.VALUE)
FOR A.NAME IN (' + @ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXECUTE sp_executesql @DynamicPivotQuery
这些名称值获得硬编码来计算@ColumnName变量。
如果这些值无论如何都是硬编码的,那么您还可以使用连接来运行数据透视表,而无需构建要执行的SQL语句。
SELECT A.Company_Name, A.Part_Number, A.Product_Desc, A.Innovate_Description, P.*
FROM (select Primary_Key, Name, Value from Innovate.dbo.Table1) T1
PIVOT(MAX(VALUE) FOR NAME IN (
[Suture_-_2nd_Needle_Code],
[Suture_-_Absorbable],
[Suture_-_Antibacterial],
[Suture_-_Armed],
[Suture_-_Barbed],
[Suture_-_Brand_Name],
[Suture_-_C/R_2nd_Needle_Code],
[Suture_-_C/R_Brand_Name],
[Suture_-_C/R_length],
[Suture_-_C/R_Needle_Code],
[Suture_-_Coating],
[Suture_-_Dyed],
[Suture_-_Filament],
[Suture_-_length_inches],
[Suture_-_Looped],
[Suture_-_Material],
[Suture_-_Needle_Code],
[Suture_-_Needle_Shape],
[Suture_-_Needle_Style],
[Suture_-_Noun],
[Suture_-_pleget],
[Suture_-_Popoff],
[Suture_-_Suture_count],
[Suture_-_Suture_size]
)
) P
LEFT JOIN Innovate.dbo.Table2 AS A ON (A.Primary_Key = P.Primary_Key);
很公平,这有一个缺点,即如果该[Primary_Key]需要为第一列,即P.*
应由那些文字列值来代替。毕竟,或者使用EXEC方法。
DECLARE @ColumnName NVARCHAR(MAX);
--Get distinct values of the PIVOT Column
SELECT @ColumnName = ISNULL(@ColumnName + ',','') + QUOTENAME(NAME)
FROM Innovate.dbo.Table1
WHERE Name Like 'Suture_-_%'
AND SUBSTRING(Name,10,30) IN (
'2nd_Needle_Code',
'Absorbable',
'Antibacterial',
'Armed',
'Barbed',
'Brand_Name',
'C/R_2nd_Needle_Code',
'C/R_Brand_Name',
'C/R_length',
'C/R_Needle_Code',
'Coating',
'Dyed',
'Filament',
'length_inches',
'Looped',
'Material',
'Needle_Code',
'Needle_Shape',
'Needle_Style',
'Noun',
'pleget',
'Popoff',
'Suture_count',
'Suture_size')
GROUP BY Name;
第一个代码很好用,因为我可以交换硬编码的值,并且无论如何我都会自己指定它们,而不是使用sql来获取动态数据透视表中的值。谢谢! –
首先改变Table1.PrimaryKey到P.PrimaryKey:
总之,建立名单为@ColumnName变量,可以没有所有的OR的完成。接下来,打印@ColumnName中的内容并将其显示给我们。 – RBarryYoung