列值作为调查结果查询中的列别名

时间:2016-10-07 15:03:16

标签: sql-server

我在构建以下方案的查询时遇到问题。我列出了一个示例表格和值:

回应表

╔═════╦═════════════╦════════════════╦══════════════════╦══════════════════╗
║ QID ║ Response_ID ║ Response_Title ║ Answer_Col_Label ║ Answer_Col_Value ║
╠═════╬═════════════╬════════════════╬══════════════════╬══════════════════╣
║  10 ║         500 ║ Blue           ║ Q10_isBlue       ║                1 ║
║  10 ║         501 ║ Green          ║ Q10_isGreen      ║                2 ║
║  10 ║         502 ║ Yellow         ║ Q10_isYellow     ║                3 ║
╚═════╩═════════════╩════════════════╩══════════════════╩══════════════════╝

然后在结果表中,值如下:

结果表

╔══════╦═════════╗
║ Q_ID ║ answers ║
╠══════╬═════════╣
║   10 ║     502 ║
╚══════╩═════════╝  

在结果表中,在答案栏中按下了response_id,这意味着用户从单选按钮/复选框中选择了此response_id。

现在我想创建一个查询,我希望在列标题中显示answer_col_label值(Lable_a),以包括响应表的所有响应,并在该列标题下显示answer_value作为选定结果。

请帮我在SQL Server中创建此查询。感谢您的时间和帮助。

编辑 - 必需的查询结果

这是查询结果的格式,我想实现:

╔════════════╦═════════════╦══════════════╗
║ Q10_isBlue ║ Q10_isGreen ║ Q10_isYellow ║
╠════════════╬═════════════╬══════════════╣
║ NULL       ║ Null        ║            3 ║
╚════════════╩═════════════╩══════════════╝

其中Q10_isYellow = 3是响应表中response_id = 502的值。结果表将与响应表连接以获取其列标签和列值,在这种情况下, “Q10_isYellow” “3”< / em> 分别。

希望此编辑部分能够进一步改进我的问题以理解我的问题。谢谢。

1 个答案:

答案 0 :(得分:0)

以下是使用动态交叉表执行此操作的一种方法。

首先,我们需要使用表格和数据。

create table #Responses
(
    QID int
    , ResponseID int
    , ResponseTitle varchar(50)
    , AnswerColLabel varchar(50)
    , AnswerColValue int
)

insert #Responses
select 10, 500, 'Blue', 'Q10_isBlue', 1 union all
select 10, 501, 'Green', 'Q10_isGreen', 2 union all
select 10, 502, 'Yellow', 'Q10_isYellow', 3

create table #Results
(
    QID int
    , answers int
)

insert #Results
select 10, 502

我也在这里使用计数表。我把它保存在我的系统中,所以我不必一遍又一遍地写它。

create View [dbo].[cteTally] as

WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
    )
select N from cteTally

既然设置了问题,我们可以查看一些代码。此技术称为动态交叉表。杰夫莫登在这里有一篇很棒的文章。 http://www.sqlservercentral.com/articles/Crosstab/65048/

declare @StaticPortion nvarchar(2000) = 'with OrderedResults as
    (
        select r.*, ru.answers, ROW_NUMBER() over(partition by r.QID order by ResponseID) as RowNum
        from #Responses r
        left join #Results ru on ru.QID = r.QID and ru.answers = r.ResponseID
    )
    select r.QID '



declare @FinalStaticPortion nvarchar(2000) = 
' from OrderedResults r 
group by r.QID'

declare @DynamicPortion nvarchar(max) = '';

select @DynamicPortion = @DynamicPortion +
    ', MAX(Case when RowNum = ' + CAST(t.N as varchar(6)) + ' then case when r.answers is not null then r.AnswerColValue end end) as ' + r.AnswerColLabel
from #Responses r
left join #Results ru on ru.QID = r.QID and ru.answers = r.ResponseID
join cteTally t on t.N = r.AnswerColValue

declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion;
--select @SqlToExecute
exec sp_executesql @SqlToExecute