【问题标题】:How to use TSQL STUFF in a Pivot?如何在 Pivot 中使用 TSQL STUFF?
【发布时间】:2018-02-26 03:50:51
【问题描述】:

我正在重写一个 TSQL 查询,该查询使用 STUFF 运算符通过问题编号水平旋转总和答案值。我已经声明了一个参数并将其设置为使用上述运算符。但是,当我将参数放在数据透视语句的 IN 部分中时,我会收到 incorrect syntax near @cols

DECLARE @cols AS NVARCHAR(MAX)

SELECT @cols = STUFF((
            SELECT ',' + QUOTENAME(ColName)
            FROM (
                SELECT DISTINCT CONVERT(VARCHAR(50), QuestionNumber) AS ColName
                FROM Questions
                WHERE StudyID = 23
                ) AS sub
            ORDER BY CONVERT(INT, ColName) ASC
            FOR XML PATH('')
                ,TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '');

WITH cteX
AS (
    SELECT q.StudyID
        ,r.RespID
        ,p.ProductNumber
        ,p.ProductSequence
        ,CONVERT(VARCHAR(50), s.DateAdded, 101) AS StudyDate
        ,CONVERT(VARCHAR(15), CAST((s.DateAdded) AS TIME), 100) AS StudyTime
        ,DATENAME(dw, s.DateAdded) AS [DayOfWeek]
        ,p.[A_Value]
        ,p.B_Value
        ,p.C_Value
        ,p.D_Value
        ,p.E_Value
        ,p.F_Value
        ,q.DependentVarYN
        ,q.VariableAttributeID
        ,v.VarAttributeName
        ,q.QuestionNumber
        ,q.BottomScaleAnchor
        ,q.BottomScaleValue
        ,q.TopScaleAnchor
        ,q.TopScaleValue
    FROM Questions q
    INNER JOIN Answers a ON q.QuestionID = a.QuestionID
    INNER JOIN Respondents r ON a.RespID = r.RespID
    INNER JOIN Products p ON a.StudyID = p.ProductID
    INNER JOIN Studies s ON q.StudyID = s.StudyID
    INNER JOIN VariableAttributesForQuestions v ON q.VariableAttributeID = v.VariableAttributeID
    )
--,
SELECT StudyID
    ,RespID
    ,ProductNumber
    ,ProductSequence
    ,StudyDate
    ,StudyTime
    ,[DayOfWeek]
    ,cteX.[A_Value] AS [A]
    ,cteX.[B_Value] AS B
    ,cteX.[C_Value] AS C
    ,cteX.[D_Value] AS D
    ,cteX.E_Value AS E
    ,cteX.F_Value AS F
    ,DependentVarYN
    ,VariableAttributeID
    ,VarAttributeName
    ,BottomScaleAnchor
    ,BottomScaleValue
    ,TopScaleAnchor
    ,TopScaleValue
FROM cteX
pivot(sum(AnswerValue) FOR cteX.QuestionNumber IN (@cols)) AS piv

如何优化查询,以便数据透视表解析每个问题的 AnswerValue 总和?

【问题讨论】:

  • 在哪一行抱怨语法不正确?
  • 你应该学习你使用的工具背后的机制,而不是仅仅应用它们而不考虑它们。你知道STUFF 在这里实际上做了什么吗?它正在从字符串中删除前导逗号。就是这样。连接等是通过滥用FOR XML 功能来完成的。将整个操作视为STUFF 是严重错误地将执行此技巧的“功劳”归因于。

标签: sql-server tsql pivot common-table-expression


【解决方案1】:

您不能像这样创建动态轴。您需要将 T-SQL 语句构建为字符串,然后执行。

DECLARE @cols AS NVARCHAR(MAX)

SELECT @cols = STUFF((
            SELECT ',' + QUOTENAME(ColName)
            FROM (
                SELECT DISTINCT CONVERT(VARCHAR(50), QuestionNumber) AS ColName
                FROM Questions
                WHERE StudyID = 23
                ) AS sub
            ORDER BY CONVERT(INT, ColName) ASC
            FOR XML PATH('')
                ,TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '');

DECLARE @DynamicTSQLStatement NVARCHAR(MAX) = N'


WITH cteX
AS (
    SELECT q.StudyID
        ,r.RespID
        ,p.ProductNumber
        ,p.ProductSequence
        ,CONVERT(VARCHAR(50), s.DateAdded, 101) AS StudyDate
        ,CONVERT(VARCHAR(15), CAST((s.DateAdded) AS TIME), 100) AS StudyTime
        ,DATENAME(dw, s.DateAdded) AS [DayOfWeek]
        ,p.[A_Value]
        ,p.B_Value
        ,p.C_Value
        ,p.D_Value
        ,p.E_Value
        ,p.F_Value
        ,q.DependentVarYN
        ,q.VariableAttributeID
        ,v.VarAttributeName
        ,q.QuestionNumber
        ,q.BottomScaleAnchor
        ,q.BottomScaleValue
        ,q.TopScaleAnchor
        ,q.TopScaleValue
    FROM Questions q
    INNER JOIN Answers a ON q.QuestionID = a.QuestionID
    INNER JOIN Respondents r ON a.RespID = r.RespID
    INNER JOIN Products p ON a.StudyID = p.ProductID
    INNER JOIN Studies s ON q.StudyID = s.StudyID
    INNER JOIN VariableAttributesForQuestions v ON q.VariableAttributeID = v.VariableAttributeID
    )
--,
SELECT StudyID
    ,RespID
    ,ProductNumber
    ,ProductSequence
    ,StudyDate
    ,StudyTime
    ,[DayOfWeek]
    ,cteX.[A_Value] AS [A]
    ,cteX.[B_Value] AS B
    ,cteX.[C_Value] AS C
    ,cteX.[D_Value] AS D
    ,cteX.E_Value AS E
    ,cteX.F_Value AS F
    ,DependentVarYN
    ,VariableAttributeID
    ,VarAttributeName
    ,BottomScaleAnchor
    ,BottomScaleValue
    ,TopScaleAnchor
    ,TopScaleValue
FROM cteX
pivot(sum(AnswerValue) FOR cteX.QuestionNumber IN (' + @cols + ')) AS piv';


exec sp_executesql @DynamicTSQLStatement;

【讨论】:

    猜你喜欢
    • 2018-04-05
    • 1970-01-01
    • 2013-11-04
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 2018-11-08
    • 1970-01-01
    相关资源
    最近更新 更多