2016-08-30 66 views
0

我正在尝试在最后两列上做一个动态数据透视表,我从一张表中取出并加入到另一张表的内容中。我需要将名称值转换为标题字段和值的值,以便在下面相应地填写。这是我当前的查询: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,因此我不知道如何多次指定它以及如何解除绑定。

+0

首先改变Table1.PrimaryKey到P.PrimaryKey:

总之,建立名单为@ColumnName变量,可以没有所有的OR的完成。接下来,打印@ColumnName中的内容并将其显示给我们。 – RBarryYoung

回答

0

你有一些事情与你的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' 
+0

马特,它看起来像你建议的查询工作,但我遇到了一个问题,因为在Table1中,所有从Attribute_Name列旋转的新列标题都无法识别(因为它们不存在),所以我一直在这些值的错误,因为它们不在该表中。有没有办法让我从连接中提取这些值以使其能够运行查询? –

+0

你能否用实际错误更新你的文章?如果你的内部查询中缺少值/注释,那么应该让你的数据透视表中的一列为NULL。 – Matt

0

与下面的脚本尝试..

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 
0

这些名称值获得硬编码来计算@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; 
+0

第一个代码很好用,因为我可以交换硬编码的值,并且无论如何我都会自己指定它们,而不是使用sql来获取动态数据透视表中的值。谢谢! –