我有像
这样的原始数据Title Question Answer AnswerRemark ---------------------------------------- ACCCode1 Q1 Y NULL ACCCode1 Q2 N 6 ACCCode1 Q3 Y Workout
正如您所看到的,“AnswerRemark”字段是“答案”的自由文本,某些答案不需要备注。
我可以简单地转动问题并回答如下:
Title Q1 Q2 Q3 AccessCode1 Y N Y
我想要的结果将是
Title Q1 R1 Q2 R2 Q3 R3 AccessCode1 Y NULL N 6 Y Workout
这可能吗?我无法弄清楚如何实现这一点,因为它有许多组合,所以答案并不是一个好主意。
有什么建议吗?
答案 0 :(得分:2)
使用条件聚合:
SELECT Title,
MAX(CASE WHEN Question='Q1' THEN Answer END) as Q1 ,
MAX(CASE WHEN Question='Q1' THEN AnswerRemark END) as R1 ,
MAX(CASE WHEN Question='Q2' THEN Answer END) as Q2 ,
MAX(CASE WHEN Question='Q2' THEN AnswerRemark END) as R2 ,
MAX(CASE WHEN Question='Q3' THEN Answer END) as Q3 ,
MAX(CASE WHEN Question='Q3' THEN AnswerRemark END) as R3
FROM [tablename]
GROUP BY Title
答案 1 :(得分:0)
使用Pivot我们得到结果
;With cte(Title, Question,Answer,AnswerRemark)
AS
(
SELECT 'ACCCode1','Q1','Y',NULL UNION ALL
SELECT 'ACCCode1','Q2','N','6' UNION ALL
SELECT 'ACCCode1','Q3','Y','Workout' UNION ALL
SELECT 'ACCCode1','Q2','N','7' UNION ALL
SELECT 'ACCCode1','Q1','Y',NULL UNION ALL
SELECT 'ACCCode1','Q3','N','9' UNION ALL
SELECT 'ACCCode1','Q1','N','4' UNION ALL
SELECT 'ACCCode1','Q2','N','Workout' UNION ALL
SELECT 'ACCCode1','Q4','N','2' UNION ALL
SELECT 'ACCCode1','Q3','Y','Workout' UNION ALL
SELECT 'ACCCode1','Q1','N','1' UNION ALL
SELECT 'ACCCode1','Q4','Y',NULL
)
SELECT *,'Remark'+CAST(ROW_NUMBER()OVER(ORDER BY (SELECT 1))AS varchar(10)) AS Question2
, ROW_NUMBER()OVER(PArtition by Question Order by Question ) AS Seq
INTO #t FROM cte
使用动态Sql,其中列不是静态的
DECLARE @DyColumn1 Nvarchar(max),
@DyColumn2 Nvarchar(max),
@Sql Nvarchar(max),
@MAxDyColumn1 Nvarchar(max),
@MAxDyColumn2 Nvarchar(max),
@CombineColumn Nvarchar(max)
SELECT @DyColumn1=STUFF((SELECT DISTINCT ', '+QUOTENAME(Question) FROM #t FOR XML PATH ('')),1,1,'')
SELECT @DyColumn2=STUFF((SELECT ', '+QUOTENAME(Question2) FROM #t FOR XML PATH ('')),1,1,'')
SELECT @MAxDyColumn1=STUFF((SELECT DISTINCT ', '+'MAX('+QUOTENAME(Question)+') AS '+QUOTENAME(Question) FROM #t FOR XML PATH ('')),1,1,'')
SELECT @MAxDyColumn2=STUFF((SELECT ', '+'MAX('+QUOTENAME(Question2)+') AS '+QUOTENAME(Question2) FROM #t FOR XML PATH ('')),1,1,'')
SELECT @CombineColumn=STUFF((SELECT DISTINCT ', '+QUOTENAME(Question)+','+QUOTENAME(Question2) FROM #t FOR XML PATH ('')),1,1,'')
SET @Sql='SELECT Title,'+@CombineColumn+' From
(
SELECT Title,'+@MAxDyColumn1+','+@MAxDyColumn2+' FRom
(
SELECT * FROM #t
)AS SRC
PIVOT
(
MAX(Answer) FOR Question IN('+@DyColumn1+')
) AS Pvt1
PIVOT
(
MAX(AnswerRemark) FOR Question2 IN('+@DyColumn2+')
) AS Pvt2
GROUP BY Title
)dt
'
PRINT @Sql
EXEC(@Sql)
结果
Title Q1 Remark1 Q1 Remark2 Q1 Remark3 Q1 Remark4 Q2 Remark5 Q2 Remark6 Q2 Remark7 Q3 Remark8 Q3 Remark9 Q3 Remark10 Q4 Remark11 Q4 Remark12
ACCCode1 Y NULL Y 1 Y 4 Y NULL N 6 N Workout N 7 Y Workout Y Workout Y 9 Y NULL Y 2
答案 2 :(得分:0)
我不知道您的数据有多大,或者可能有多少问题。在表示层完成的更通用的Q& A结构会好得多,但是对于您的特定请求,更正确的设计将是3NF表。这将允许您创建高度优化的主键,并按问题类型ID创建二级索引。现在所有的密钥都是ID,搜索和匹配的速度比字符串快得多:
Account Codes
AccID - AccName - columns for other data related to accounts
存储您拥有的每个帐户。
Questions
QuestionID - QuestionName
可能的问题列表,每个问题都有一行,Q1,Q2等。您可以在此处添加问题类别以利用您拥有的任何共性,例如:如果您对同一组问题进行了不同的调查,您可以将它们放在一个类别中,然后轻松查询下面的内容。
Results
AccId, QuestionID, Result, Result Remark
每个问题都包含一行。
查询结果仍然使用pivot,但现在您可以从变量或动态SQL语法中选择要使用的列列表,这意味着您可以更好地控制它,并且查询本身应该更好。
话虽如此,如果您对数据有任何了解,可以使用它来制作静态查询,然后可以将其编入索引。此查询的示例如下:SQL Server 2005 Pivot on Unknown Number of Columns。然后,您可以根据需要使用AS语法设置列名称,遗憾的是,这会再次需要动态sql(Change column name while using PIVOT SQL Server 2008)。
顺便说一句,你要做的是专门处理非规范化数据,这是nosql的优点,SQL Server为你提供了很大帮助,但你必须对你的数据有一些结构。
如果你不是为调查猴子工作并处理数以百万计的变种,我会认真考虑你是否可以只针对你得到的每一轮问题制作一个表格,然后简单地对其进行非规范化并添加一个明确的每个问题的列,然后将整个逻辑设为select * from surveyxyztable where accountid = abc
。