Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何在SQL Server 2008中将行更改为列(多个表、联接等)_Sql Server_Pivot_Dynamic Sql_Dynamic Columns - Fatal编程技术网

Sql server 如何在SQL Server 2008中将行更改为列(多个表、联接等)

Sql server 如何在SQL Server 2008中将行更改为列(多个表、联接等),sql-server,pivot,dynamic-sql,dynamic-columns,Sql Server,Pivot,Dynamic Sql,Dynamic Columns,我需要帮助为调查应用程序创建报告。 涉及5个主要表格: 调查(ID、报告列名称) 节(ID、节名称) 调查部分(FK调查、FK调查部分、活动) Section_Surveys_ScoreValue(FK_Surveys,FK_Section,FK_ScoreCategories,Section ScoreValue) ScoreCategories(ID、ScoreStart、ScoreEnd、CategoryName) 每次创建调查时,都会生成一个新的ReportColumnName,该列

我需要帮助为调查应用程序创建报告。 涉及5个主要表格:

  • 调查(ID、报告列名称)
  • 节(ID、节名称)
  • 调查部分(FK调查、FK调查部分、活动)
  • Section_Surveys_ScoreValue(FK_Surveys,FK_Section,FK_ScoreCategories,Section ScoreValue)
  • ScoreCategories(ID、ScoreStart、ScoreEnd、CategoryName)
每次创建调查时,都会生成一个新的
ReportColumnName
,该列需要成为报告中的一列。对于这些列中的每一列和每个部分(在调查中处于活动状态),都将有一个
SectionScoreValue
。这将进一步链接并检查它是否在
ScoreCategories
的间隔内,并为每个调查和部分显示结果类别(
CategoryName

我一直在寻找如何正确地透视这些列并正确地显示所需的值。通过对从网站上获得的一些代码进行改编,我认为这是可行的:

declare @SQL nvarchar(max), @Cols nvarchar(max)
select @Cols = 
stuff(
(
  select ', ' + quotename(dt)
  from 
  (
    select TOP 100 PERCENT Sv.ID, Sv.ReportColumnName as dt 
    from Surveys AS Sv
    ORDER BY Sv.ID
  ) X
  ORDER BY X.ID FOR XML PATH('')
),1,1,''
)

SELECT @Cols

set @SQL = 
'SELECT Sv.ReportColumnName, SSSV.* 
FROM Surveys AS Sv 
INNER JOIN Sections_Surveys__ScoreValues AS SSSV
   ON SSSV.FK_Surveys_ID = Sv.ID
INNER JOIN Sections AS Sc
   ON Sc.ID = SSSV.FK_Sections_ID
INNER JOIN Sections_Surveys AS SS 
   ON SS.FK_Surveys_ID = Sv.ID
   AND SS.FK_Sections_ID = Sc.ID
INNER JOIN ScoreCategories AS ScoreC 
   ON ScoreC.ID = SSSV.FK_ScoreCategories_ID

PIVOT (max(SSSV.SectionScoreValue) FOR Sv.ReportColumnName IN (' + @Cols
+')) pvt'

execute (@sql)
@Cols
变量保存我需要的列(即调查名称),并正确显示它们(并用逗号分隔)。所以这部分工作正常

我的问题是,下一部分应该(最初)为每个
SectionName
(在第一列)和每个调查(每个调查在单独的列上)设置
SectionScoreValue

这些调查列是在创建新列时动态添加的,因此它们永远不是常量

每个表都有一个
CreateDate
列,默认值为
GetDATE()
。我得到的错误是:

为“pvt”多次指定了列“CreateDate”。
无法绑定多部分标识符“Sv.ReportColumnName”。
列前缀“SSSV”与查询中使用的表名或别名不匹配

请帮助正确显示我的数据。它应该显示如下内容:

Section Survey1 Survey2 Survey3 ......
s1        1.33    1.66    2.5
s2        0.00    3.33    4
s3        2.33    2       1.66
s4        0.66    2.5     3
数字也可以替换为ScoreCategoryName中的值(根据数字所在的时间间隔,如“良好”、“优秀”等)

多谢各位

编辑1:这是
PRINT@SQL
产生的结果:

SELECT Sv.ReportColumnName, SSSV.* 
FROM Surveys AS Sv 
INNER JOIN Sections_Surveys__ScoreValues AS SSSV
    ON SSSV.FK_Surveys_ID = Sv.ID
INNER JOIN Sections AS Sc
    ON Sc.ID = SSSV.FK_Sections_ID
INNER JOIN Sections_Surveys AS SS 
    ON SS.FK_Surveys_ID = Sv.ID
    AND SS.FK_Sections_ID = Sc.ID
INNER JOIN ScoreCategories AS ScoreC 
    ON ScoreC.ID = SSSV.FK_ScoreCategories_ID

PIVOT (max(SSSV.SectionScoreValue) FOR Sv.ReportColumnName 
IN ( [S1-1-2 -3], [S217], [al 3], [S37], [R4], [ult_nume_col])) pvt
编辑2:多亏了乔治,我终于找到了解决方案!下面是最后的代码,它显示了我需要的列:

declare @SQL nvarchar(max), @Cols nvarchar(max)
select @Cols = 
stuff(
(
    select ', ' + quotename(dt)
    from 
    (
        select TOP 100 PERCENT Sv.ID, Sv.ReportColumnName as dt 
        from Surveys AS Sv
        ORDER BY Sv.ID
    ) X
    ORDER BY X.ID FOR XML PATH('')



),1,1,''
)

SELECT @Cols

SET @SQL = ';
WITH    cte
          AS ( SELECT Sv.CreateDate, Sv.ReportColumnName, Sc.SectionName, SSSV.SectionScoreValue 
                FROM Surveys AS Sv 
                INNER JOIN Sections_Surveys__ScoreValues AS SSSV
                    ON SSSV.FK_Surveys_ID = Sv.ID
                INNER JOIN Sections AS Sc
                    ON Sc.ID = SSSV.FK_Sections_ID
                INNER JOIN Sections_Surveys AS SS 
                    ON SS.FK_Surveys_ID = Sv.ID
                    AND SS.FK_Sections_ID = Sc.ID
                INNER JOIN ScoreCategories AS ScoreC 
                    ON ScoreC.ID = SSSV.FK_ScoreCategories_ID
             )
    SELECT  SectionName , ' + @Cols + '
    FROM    cte PIVOT ( MAX(cte.SectionScoreValue) FOR cte.ReportColumnName IN (' + @Cols + ') ) pvt'

print @sql

execute (@sql)

感谢所有的帮助,感谢“投票否决”(如果我能自己得出结果,我就不会在这里发布了)。

使用数据透视拨号时始终使用表格表达式。大概是这样的:

SET @SQL = ';
WITH    cte
          AS ( SELECT   SSSV.SectionScoreValue ,
                        Sv.ReportColumnName ,
                        Section
               FROM     Surveys AS Sv
                        INNER JOIN Sections_Surveys__ScoreValues AS SSSV ON SSSV.FK_Surveys_ID = Sv.ID
                        INNER JOIN Sections AS Sc ON Sc.ID = SSSV.FK_Sections_ID
                        INNER JOIN Sections_Surveys AS SS ON SS.FK_Surveys_ID = Sv.ID AND SS.FK_Sections_ID = Sc.ID
                        INNER JOIN ScoreCategories AS ScoreC ON ScoreC.ID = SSSV.FK_ScoreCategories_ID
             )
    SELECT  Section , ' + @Cols + '
    FROM    cte PIVOT ( MAX(SSSV.SectionScoreValue) FOR Sv.ReportColumnName IN (' + @Cols + ') ) pvt'
你也可以看看我对类似问题的回答:


我建议先用硬编码的列来写,以确保逻辑正确,然后再转换。另外,如果您发布每个表的示例数据以及表结构,则更容易找出问题所在。您还可以
print@sql
查看查询语法是什么,然后从那里进行调试。能否发布生成此错误的sql变量的示例值?感谢您的回复。我用Print@SQL的值编辑了OP;PIVOT中似乎存在一个问题,即那些动态列名,但我不知道如何修复它们(因为它们的数量会一直变化)。类似的情况似乎在我尝试调整代码的地方起作用。@XYZ只是猜测,但您是否尝试将
select'、'+quotename(dt)
更改为
select distinct'、'+quotename(dt)
?错误:如果指定了select distinct,则按项目排序必须出现在选择列表中。当我尝试将其添加到ORDERBY子句时,它不起作用(可能是因为其中有一个FORXML路径)!经过几次修改后,我让它工作了(并更新了OP)。