应用 PIVOT 运算符时出错

Posted

技术标签:

【中文标题】应用 PIVOT 运算符时出错【英文标题】:Getting error while applying PIVOT operator 【发布时间】:2021-06-15 07:05:09 【问题描述】:

我必须在几个表上应用联接,这些表具有用户以问题形式进行的评估的一些详细信息。有些评估有 10 个问题,而其他评估可能只有 5 个。问题的答案需要显示为列而不是行。 我准备了以下查询:

IF OBJECT_ID(N'tempdb..#VALS') IS NOT NULL 
BEGIN
DROP TABLE #VALS
END
GO
DECLARE @SQL NVARCHAR(MAX)
DECLARE @VALS NVARCHAR(MAX)
SELECT DISTINCT SUBSTRING('QuestionText', 1, 100) AS Vals
INTO #VALS FROM Analytics.DimEvaluation
SELECT @VALS = COALESCE(@VALS+', ','') + '[' + VALS + ']' FROM #VALS
SET @SQL = 'SELECT top 10
Act.ActivityCode as [Region]
    ,Act.ActivityType AS [Activity Type]
    ,Act.ActivityCode AS [Activity Code]
    ,Act.ActivityName AS [Activity Name]
    ,CONVERT(DATETIME, Act.StartDate, 102) AS [Activity Start Time]
    ,CONVERT(DATETIME, Act.EndDate, 102) AS [Activity End Time]
    ,DimLoc.FacilityName AS [Facility]
    ,DimLoc.FacilityCity + '''' + DimLoc.FacilityCountry AS [Facility City, Facility Country]
    ,Act.EstimatedCreditHours AS [Estimated Credit Hours]
    ,REPLACE(Emp.ImportKey, '','', '''') AS [User Global ID]
    ,(SELECT NoteText FROM PERSON WITH (NOLOCK) WHERE PersonPk = emp.SourceID) AS [Local Employee Number]
    ,Emp.FirstName AS [First Name]
    ,Emp.LastName AS [Last Name]
    ,Emp.FirstName + '''' + Emp.LastName AS [User Full Name]
    ,Emp.Email AS [User Email]
    ,'+@VALS+' 
    AS [STTEST]
FROM Analytics.DimActivity AS Act WITH (NOLOCK)
INNER JOIN Analytics.FactActivityLocation factResLoc WITH (NOLOCK) ON factResLoc.DimActivityId = Act.DimActivityId
LEFT OUTER JOIN Analytics.DimLocation DimLoc WITH (NOLOCK) ON DimLoc.DimLocationId = factResLoc.DimLocationId
INNER JOIN Analytics.FactActivityAttempt FACT WITH (NOLOCK) ON fact.DimActivityId = Act.DimActivityId
INNER JOIN Analytics.DimEmployee Emp WITH (NOLOCK) ON Emp.DimEmployeeID = fact.Dimemployeeid
inner join Analytics.FactEvaluation FactEval WITH (NOLOCK) on FactEval.DimActivityId = Act.DimActivityId
inner join Analytics.DimEvaluation DimEval WITH (NOLOCK) on FactEval.DimEvaluationId = DimEval.DimEvaluationId
PIVOT(MIN([Answer]) FOR [QuestionText] IN ('+@VALS+')) PIV'
PRINT @SQL
EXEC(@SQL)
但是在执行时,我遇到了以下错误:
(1 row(s) affected)
SELECT top 10 Act.ActivityCode as [Region]
         ,Act.ActivityType AS [Activity Type]
         ,Act.ActivityCode AS [Activity Code]
         ,Act.ActivityName AS [Activity Name]
         ,CONVERT(DATETIME, Act.StartDate, 102) AS [Activity Start Time]
         ,CONVERT(DATETIME, Act.EndDate, 102) AS [Activity End Time]
         ,DimLoc.FacilityName AS [Facility]
         ,DimLoc.FacilityCity + '' + DimLoc.FacilityCountry AS [Facility City, Facility Country]
          ,Act.EstimatedCreditHours AS [Estimated Credit Hours]
         ,REPLACE(Emp.ImportKey, ',', '') AS [User Global ID]
         ,(SELECT NoteText FROM PERSON WITH (NOLOCK)     WHERE PersonPk = emp.SourceID) AS [Local Employee Number]
         ,Emp.FirstName AS [First Name]
         ,Emp.LastName AS [Last Name]
         ,Emp.FirstName + '' + Emp.LastName AS [User Full Name]
         ,Emp.Email AS [User Email]
         ,[QuestionText] 
         AS [STTEST]
FROM Analytics.DimActivity AS Act WITH (NOLOCK)
INNER JOIN Analytics.FactActivityLocation factResLoc WITH (NOLOCK) ON factResLoc.DimActivityId = Act.DimActivityId
LEFT OUTER JOIN Analytics.DimLocation DimLoc WITH (NOLOCK) ON DimLoc.DimLocationId = factResLoc.DimLocationId
INNER JOIN Analytics.FactActivityAttempt FACT WITH (NOLOCK) ON fact.DimActivityId = Act.DimActivityId
INNER JOIN Analytics.DimEmployee Emp WITH (NOLOCK) ON Emp.DimEmployeeID = fact.Dimemployeeid
inner join Analytics.FactEvaluation FactEval WITH (NOLOCK) on FactEval.DimActivityId = Act.DimActivityId
inner join Analytics.DimEvaluation DimEval WITH (NOLOCK) on FactEval.DimEvaluationId = DimEval.DimEvaluationId
PIVOT(MIN([Answer]) FOR [QuestionText] IN ([QuestionText])) PIV
Msg 265, Level 16, State 1, Line 35
The column name "QuestionText" specified in the PIVOT operator conflicts with the existing column name in the PIVOT argument.
Msg 8156, Level 16, State 1, Line 35
The column 'DimActivityId' was specified multiple times for 'PIV'.
Msg 4104, Level 16, State 1, Line 8
The multi-part identifier "Act.ActivityCode" could not be bound.
Msg 4104, Level 16, State 1, Line 9
The multi-part identifier "Act.ActivityType" could not be bound.
Msg 4104, Level 16, State 1, Line 10
The multi-part identifier "Act.ActivityCode" could not be bound.
Msg 4104, Level 16, State 1, Line 11
The multi-part identifier "Act.ActivityName" could not be bound.
Msg 4104, Level 16, State 1, Line 12
The multi-part identifier "Act.StartDate" could not be bound.
Msg 4104, Level 16, State 1, Line 13
The multi-part identifier "Act.EndDate" could not be bound.
Msg 4104, Level 16, State 1, Line 14
The multi-part identifier "DimLoc.FacilityName" could not be bound.
Msg 4104, Level 16, State 1, Line 15
The multi-part identifier "DimLoc.FacilityCity" could not be bound.
Msg 4104, Level 16, State 1, Line 15
The multi-part identifier "DimLoc.FacilityCountry" could not be bound.
Msg 4104, Level 16, State 1, Line 16
The multi-part identifier "Act.EstimatedCreditHours" could not be bound.
Msg 4104, Level 16, State 1, Line 17
The multi-part identifier "Emp.ImportKey" could not be bound.
Msg 4104, Level 16, State 1, Line 18
The multi-part identifier "emp.SourceID" could not be bound.
Msg 4104, Level 16, State 1, Line 19
The multi-part identifier "Emp.FirstName" could not be bound.
Msg 4104, Level 16, State 1, Line 20
The multi-part identifier "Emp.LastName" could not be bound.
Msg 4104, Level 16, State 1, Line 21
The multi-part identifier "Emp.FirstName" could not be bound.
Msg 4104, Level 16, State 1, Line 21
The multi-part identifier "Emp.LastName" could not be bound.
Msg 4104, Level 16, State 1, Line 22
The multi-part identifier "Emp.Email" could not be bound.

在识别错误​​和解决错误方面需要帮助。 提前致谢。

【问题讨论】:

Stop splattering NOLOCK everywhere,这不是“更快”的开关,而是“给出不正确的结果”的开关。但这并不能解决您的问题,即您需要进行子查询,因为您不能在同一级别的查询中使用 JOINPIVOT 【参考方案1】:

您肯定想要来自 QuestionText 列的不同值,而不是它的名称

..
SELECT DISTINCT SUBSTRING(QuestionText, 1, 100) AS Vals
INTO #VALS 
FROM Analytics.DimEvaluation;
..

顺便说一句NOLOCK,希望你知道你在做什么。如果当时正在运行任何更新,您可能会得到不一致的结果。

【讨论】:

Msg 8156, Level 16, State 1, Line 529 为“PIV”多次指定了“DimActivityId”列。消息 4104,级别 16,状态 1,第 8 行 无法绑定多部分标识符“Act.ActivityCode”。消息 4104,级别 16,状态 1,第 9 行无法绑定多部分标识符“Act.ActivityType”。 尝试逐步调试,每个子查询。超过 529 行的查询代码可能太大而无法调试。

以上是关于应用 PIVOT 运算符时出错的主要内容,如果未能解决你的问题,请参考以下文章

SQL中PIVOT 行列转换

ORACLE one hot encoding:对所有可用列使用 PIVOT 运算符

Pandas-数据聚合与分组运算

T-Sql语法:行转列(pivot)和列转行(unpivot)

实现重载运算符'<<'时出错 - C++

使用扩展运算符更新 usehook 对象时出错