SQL 动态数据透视表查询
SQL Dynamic Pivot Query
如果可能的话,我需要有关支点的帮助 table。不确定是否可以完成。下面是我的例子。
问题
答案
用户回答
答案轴
感谢您的帮助。
我附上了数据透视表工作时数据库结果的屏幕截图。下面的代码按原样运行并且工作正常。如果您可以查看 "Subject has exp..." 栏,我希望该栏重复三遍,标题是问题,但我也希望每个可能的答案都与问题一起显示。
再次感谢!
再次感谢。
这是代码示例:
DECLARE @columns VARCHAR(MAX)
SELECT @columns = COALESCE(@columns + ','+QUOTENAME([QuestionText]),QUOTENAME([QuestionText]))
FROM SchemaWema.vts_vwSurvey INNER JOIN
Question ON SchemaWema.vts_vwSurvey.SurveyID = SchemaWema.vts_vwQuestion.SurveyID
WHERE SchemaWema.vts_vwSurvey.DecisionSetId = 598 AND SchemaWema.vts_vwSurvey.FormType = 1
Set @columns = REPLACE(@columns, '[]', '[No Name Given]')
DECLARE @sql NVARCHAR(MAX)=N' SELECT * FROM
(
SELECT Project.PROJECTNAME, Project.ID,
Sites.PROJECTSTUDYSITENUMBER, Sites.PROJECTSTUDYSITENAME,
Study.PROJECTSTUDYNAME, Study.PROJECTSTUDYNUMBER,
Survey.SurveyID, Question.QuestionID, Cases.SITEID, Cases.EVENTDATE,
Cases.SUBJNO, Cases.EventType, Cases.TriggerEvent,
Cases.DecisionSetID, Cases.PanelID, Cases.RECORDSTATUS,
Project.PROJECTSPONSOR, VoterAnswers.AnswerID, VoterAnswers.VoterID,
VoterAnswers.AnswerText AS FreeTypedAnswers, Voter.VoteDate, Users.SHOWNNAME, Panel.PANELNAME, Sites.COUNTRY,
Cases.VERSIONID, cases.CSID, cases.CASENUMBER,Cases.CASEDATEUPDATED AS LASTUPDATED,
Cases.DECISIONSETNAME,
Question.QuestionText,
CASE
WHEN
CAST(VoterAnswers.AnswerText AS VARCHAR(MAX)) IS NULL OR CAST(VoterAnswers.AnswerText AS VARCHAR(MAX)) = ''''
THEN
Answer.AnswerText
ELSE
CAST(Answer.AnswerText AS VARCHAR(MAX))
END AS AnswerText
FROM
(
SELECT a.ID, a.STUDYID, a.SITEID, a.CSID, a.VERSIONID, a.CASENUMBER, a.CASEINITIALS, a.EVENTDATE, a.CASEDETAILSFILE, a.CASEDETAILSFILEVERSION,
a.CASESTATUS, a.RECORDSTATUS, a.CASEDATEUPDATED, a.PROJECTDATEUPDATED, a.PanelID, a.DecisionSetID, a.SUBJNO, a.EventType, a.TriggerEvent,
a.Priority, a.id1, a.id2, a.dateid, a.dateiddt1, a.dateiddt2, a.extratext1, a.extratext2, SchemaWema.PROJECTPANELDECISIONSETVIEW.DECISIONSETNAME
FROM SchemaWema.PROJECTCASE AS a LEFT OUTER JOIN
SchemaWema.PROJECTPANELDECISIONSETVIEW ON a.DecisionSetID = SchemaWema.PROJECTPANELDECISIONSETVIEW.DECISIONSETID
WHERE (a.CASEDATEUPDATED =
(SELECT MAX(CASEDATEUPDATED) AS Expr1
FROM SchemaWema.PROJECTCASE AS b
WHERE (a.ID = PROJECTID) AND (a.CSID = CASEID) AND (a.VERSIONID = VERSIONID) )) AND (a.RECORDSTATUS <> ''D'')
)Cases
LEFT OUTER JOIN
(
SELECT PROJECTID, PROJECTNAME, PROJECTSPONSOR
FROM SchemaWema.PROJECT AS a
WHERE (PROJECTDATEUPDATED =
(SELECT MAX(PROJECTDATEUPDATED) AS Expr1
FROM SchemaWema.PROJECT AS b
WHERE (a.ID = PROJECTID))) AND (RECORDSTATUS <> ''D'')
) Project on
Project.ID = Cases.ID
LEFT OUTER JOIN
(
SELECT DISTINCT a.ID, a.STUDYID, a.SITEID, a.PROJECTSTUDYSITENAME, a.PROJECTSTUDYSITENUMBER, SchemaWema.PROJECTSTUDYVIEW.PROJECTSTUDYNAME, a.COUNTRY
FROM SchemaWema.PROJECTSTUDYSITE AS a INNER JOIN
SchemaWema.PROJECTVIEW ON a.ID = SchemaWema.PROJECTVIEW.ID INNER JOIN
SchemaWema.PROJECTSTUDYVIEW ON a.ID = SchemaWema.PROJECTSTUDYVIEW.ID AND
a.STUDYID = SchemaWema.PROJECTSTUDYVIEW.STUDYID
WHERE (a.PROJECTSTUDYSITEDATEUPDATED =
(SELECT MAX(PROJECTSTUDYSITEDATEUPDATED) AS Expr1
FROM SchemaWema.PROJECTSTUDYSITE AS b
WHERE (a.ID = PROJECTID) AND (a.STUDYID = STUDYID) AND (a.SITEID = SITEID))) AND (a.RECORDSTATUS <> ''D'')
)Sites on
Cases.SITEID = Sites.SITEID
LEFT OUTER JOIN
(
SELECT DISTINCT PROJECTID, STUDYID, PROJECTSTUDYNAME, PROJECTSTUDYNUMBER, PROJECTSTUDYDESCRIPTION
FROM SchemaWema.PROJECTSTUDY AS a
WHERE (PROJECTSTUDYDATEUPDATED =
(SELECT MAX(PROJECTSTUDYDATEUPDATED) AS Expr1
FROM SchemaWema.PROJECTSTUDY AS b
WHERE (a.ID = PROJECTID) AND (ISNULL(a.STUDYID, ''0'') = ISNULL(STUDYID, ''0'')))) AND (RECORDSTATUS <> ''D'')
)Study on
Study.STUDYID = Cases.STUDYID
inner join
(
SELECT VoterID, UID, SurveyID, ContextUserName, VoteDate, StartDate, IPSource, Validated, ResumeUID, ResumeAtPageNumber, ProgressSaveDate,
ResumeQuestionNumber, ResumeHighestPageNumber, LanguageCode, SurveyStatus, VoteAcceptRejectDate, CaseID, VersionID, PdfFileName, voterSurveyStatus,
dateupdated, recordstatus, modifiedby, changereason
FROM SchemaWema.vts_tbVoter AS a
WHERE (dateupdated =
(SELECT MAX(dateupdated) AS Expr1
FROM SchemaWema.vts_tbVoter AS b
WHERE (a.VoterID = VoterID) AND (a.SurveyID = SurveyID) AND (a.CSID = CaseID) AND (a.VersionID = VersionID)))
) Voter on
Voter.CSID = Cases.CSID
AND Voter.VersionID = Cases.VersionID
Inner Join
(
SELECT DISTINCT SurveyID, DecisionSetId, FormType
FROM SchemaWema.vts_tbSurvey AS a
WHERE (dateupdated =
(SELECT MAX(dateupdated) AS Expr1
FROM SchemaWema.vts_tbSurvey AS b
WHERE (a.SurveyID = SurveyID))) AND (recordstatus <> ''D'')
) Survey on
Survey.SurveyID = Voter.SurveyID
inner Join
(
SELECT DISTINCT
VoterID, AnswerID, SectionNumber, CAST(AnswerText AS varchar(MAX)) AnswerText, SurveyID, CaseID, versionID
FROM SchemaWema.vts_tbVoterAnswers AS a
WHERE (dateupdated =
(SELECT MAX(dateupdated) AS Expr1
FROM SchemaWema.vts_tbVoterAnswers AS b
WHERE (a.VoterID = VoterID) AND (a.AnswerID = AnswerID) AND (a.SectionNumber = SectionNumber) AND (a.SurveyID = SurveyID) AND (a.CSID = CaseID) AND
(a.versionID = versionID))) AND (recordstatus <> ''D'')
)VoterAnswers on
VoterAnswers.SurveyID = Survey.SurveyID
AND VoterAnswers.CSID = Voter.CSID
AND Voter.VoterID = VoterAnswers.VoterID
AND VoterAnswers.versionID = Voter.versionID
AND VoterAnswers.SurveyID = Voter.SurveyID
FULL OUTER JOIN
(
select DISTINCT a.USERID, a.USERNAME, a.FIRSTNAME, a.LASTNAME, a.SHOWNNAME
from SchemaWema.users as a
WHERE (a.userdateupdated =
(SELECT MAX(b.userdateupdated) AS Expr1
FROM SchemaWema.users AS b
WHERE (a.userID = b.userID) ))
AND (a.RECORDSTATUS <> ''D'')
) Users on
VoterAnswers.VoterID = Users.USERID
AND Voter.VoterID = Users.USERID
inner join
(
SELECT DISTINCT AnswerID, QuestionID, AnswerText FROM SchemaWema.vts_tbAnswer AS a
WHERE (dateupdated =
(SELECT MAX(dateupdated) AS Expr1
FROM SchemaWema.vts_tbAnswer AS b
WHERE (a.AnswerID = AnswerID))) AND (recordstatus <> ''D'')
) Answer on
Answer.AnswerID = VoterAnswers.AnswerID
inner Join
(
SELECT DISTINCT QuestionID,SurveyID, QuestionText
FROM SchemaWema.vts_tbQuestion AS a
WHERE (dateupdated =
(SELECT MAX(dateupdated) AS Expr1
FROM SchemaWema.vts_tbQuestion AS b
WHERE (a.QuestionID = QuestionID))) AND (recordstatus <> ''D'')
) Question on
Answer.QuestionID = Question.QuestionID
AND Question.SurveyID = Survey.SurveyID
AND Question.SurveyID = VoterAnswers.SurveyID
inner join
(
SELECT DIStinct
[PANELID] ,[PANELNAME]
FROM [AdjudicateV3].[Adjudicate].[PROJECTPANELVIEW]
)Panel on
Panel.PANELID = Cases.PanelID
WHERE CASEs.ID = ' + @ID + ' AND Survey.DecisionSetId = '+ DeeSetId +' AND Survey.FormType = '+ @Forms +'
) AS SourceTable
PIVOT
(
MAX(AnswerText)
FOR QuestionText IN ('+@columns+')
) AS PivotTable'
可以使用动态枢轴来完成。
您要做的第一件事是构建要用于数据透视表的列。
declare @cols varchar(max)
select @cols = Coalesce(@cols + ', ', '') + '[' + q.Question + '(' + a.Question + ')]'
from Questions q
join Answers a on q.ID = a.QuestionID
这会将您想要的所有列 headers 连接成一个字符串,例如
[What is your favorite Car Color(Blue)], [What is your favorite Car Color(Red)]
将列名放在括号内很重要...
下一步是构建数据透视查询
declare @sql varchar(max)
set @sql = 'Select [User], ' + @cols + ' from (
select ua.[User], ''X'' as Chosen,
q.Question + ''('' + a.Question + '')'' Answer
from UserAnswers ua
join Answers a On ua.AnswerId = a.ID and ua.QuestionID = a.QuestionID
join Questions q on a.QuestionID = q.ID
) t
pivot (
max(Chosen)
for Answer IN (' + @cols + ')
) p'
exec(@sql)
这将创建一个包含三列用户、选择、答案的子查询。用户是用户名,选择的只是每条记录的 X,以及用于转换的答案。答案看起来像上面没有括号的列名..
接下来它旋转子查询..并选择名称和动态列..
如果可能的话,我需要有关支点的帮助 table。不确定是否可以完成。下面是我的例子。 问题
答案
用户回答
答案轴
感谢您的帮助。
我附上了数据透视表工作时数据库结果的屏幕截图。下面的代码按原样运行并且工作正常。如果您可以查看 "Subject has exp..." 栏,我希望该栏重复三遍,标题是问题,但我也希望每个可能的答案都与问题一起显示。
再次感谢!
再次感谢。
这是代码示例:
DECLARE @columns VARCHAR(MAX)
SELECT @columns = COALESCE(@columns + ','+QUOTENAME([QuestionText]),QUOTENAME([QuestionText]))
FROM SchemaWema.vts_vwSurvey INNER JOIN
Question ON SchemaWema.vts_vwSurvey.SurveyID = SchemaWema.vts_vwQuestion.SurveyID
WHERE SchemaWema.vts_vwSurvey.DecisionSetId = 598 AND SchemaWema.vts_vwSurvey.FormType = 1
Set @columns = REPLACE(@columns, '[]', '[No Name Given]')
DECLARE @sql NVARCHAR(MAX)=N' SELECT * FROM
(
SELECT Project.PROJECTNAME, Project.ID,
Sites.PROJECTSTUDYSITENUMBER, Sites.PROJECTSTUDYSITENAME,
Study.PROJECTSTUDYNAME, Study.PROJECTSTUDYNUMBER,
Survey.SurveyID, Question.QuestionID, Cases.SITEID, Cases.EVENTDATE,
Cases.SUBJNO, Cases.EventType, Cases.TriggerEvent,
Cases.DecisionSetID, Cases.PanelID, Cases.RECORDSTATUS,
Project.PROJECTSPONSOR, VoterAnswers.AnswerID, VoterAnswers.VoterID,
VoterAnswers.AnswerText AS FreeTypedAnswers, Voter.VoteDate, Users.SHOWNNAME, Panel.PANELNAME, Sites.COUNTRY,
Cases.VERSIONID, cases.CSID, cases.CASENUMBER,Cases.CASEDATEUPDATED AS LASTUPDATED,
Cases.DECISIONSETNAME,
Question.QuestionText,
CASE
WHEN
CAST(VoterAnswers.AnswerText AS VARCHAR(MAX)) IS NULL OR CAST(VoterAnswers.AnswerText AS VARCHAR(MAX)) = ''''
THEN
Answer.AnswerText
ELSE
CAST(Answer.AnswerText AS VARCHAR(MAX))
END AS AnswerText
FROM
(
SELECT a.ID, a.STUDYID, a.SITEID, a.CSID, a.VERSIONID, a.CASENUMBER, a.CASEINITIALS, a.EVENTDATE, a.CASEDETAILSFILE, a.CASEDETAILSFILEVERSION,
a.CASESTATUS, a.RECORDSTATUS, a.CASEDATEUPDATED, a.PROJECTDATEUPDATED, a.PanelID, a.DecisionSetID, a.SUBJNO, a.EventType, a.TriggerEvent,
a.Priority, a.id1, a.id2, a.dateid, a.dateiddt1, a.dateiddt2, a.extratext1, a.extratext2, SchemaWema.PROJECTPANELDECISIONSETVIEW.DECISIONSETNAME
FROM SchemaWema.PROJECTCASE AS a LEFT OUTER JOIN
SchemaWema.PROJECTPANELDECISIONSETVIEW ON a.DecisionSetID = SchemaWema.PROJECTPANELDECISIONSETVIEW.DECISIONSETID
WHERE (a.CASEDATEUPDATED =
(SELECT MAX(CASEDATEUPDATED) AS Expr1
FROM SchemaWema.PROJECTCASE AS b
WHERE (a.ID = PROJECTID) AND (a.CSID = CASEID) AND (a.VERSIONID = VERSIONID) )) AND (a.RECORDSTATUS <> ''D'')
)Cases
LEFT OUTER JOIN
(
SELECT PROJECTID, PROJECTNAME, PROJECTSPONSOR
FROM SchemaWema.PROJECT AS a
WHERE (PROJECTDATEUPDATED =
(SELECT MAX(PROJECTDATEUPDATED) AS Expr1
FROM SchemaWema.PROJECT AS b
WHERE (a.ID = PROJECTID))) AND (RECORDSTATUS <> ''D'')
) Project on
Project.ID = Cases.ID
LEFT OUTER JOIN
(
SELECT DISTINCT a.ID, a.STUDYID, a.SITEID, a.PROJECTSTUDYSITENAME, a.PROJECTSTUDYSITENUMBER, SchemaWema.PROJECTSTUDYVIEW.PROJECTSTUDYNAME, a.COUNTRY
FROM SchemaWema.PROJECTSTUDYSITE AS a INNER JOIN
SchemaWema.PROJECTVIEW ON a.ID = SchemaWema.PROJECTVIEW.ID INNER JOIN
SchemaWema.PROJECTSTUDYVIEW ON a.ID = SchemaWema.PROJECTSTUDYVIEW.ID AND
a.STUDYID = SchemaWema.PROJECTSTUDYVIEW.STUDYID
WHERE (a.PROJECTSTUDYSITEDATEUPDATED =
(SELECT MAX(PROJECTSTUDYSITEDATEUPDATED) AS Expr1
FROM SchemaWema.PROJECTSTUDYSITE AS b
WHERE (a.ID = PROJECTID) AND (a.STUDYID = STUDYID) AND (a.SITEID = SITEID))) AND (a.RECORDSTATUS <> ''D'')
)Sites on
Cases.SITEID = Sites.SITEID
LEFT OUTER JOIN
(
SELECT DISTINCT PROJECTID, STUDYID, PROJECTSTUDYNAME, PROJECTSTUDYNUMBER, PROJECTSTUDYDESCRIPTION
FROM SchemaWema.PROJECTSTUDY AS a
WHERE (PROJECTSTUDYDATEUPDATED =
(SELECT MAX(PROJECTSTUDYDATEUPDATED) AS Expr1
FROM SchemaWema.PROJECTSTUDY AS b
WHERE (a.ID = PROJECTID) AND (ISNULL(a.STUDYID, ''0'') = ISNULL(STUDYID, ''0'')))) AND (RECORDSTATUS <> ''D'')
)Study on
Study.STUDYID = Cases.STUDYID
inner join
(
SELECT VoterID, UID, SurveyID, ContextUserName, VoteDate, StartDate, IPSource, Validated, ResumeUID, ResumeAtPageNumber, ProgressSaveDate,
ResumeQuestionNumber, ResumeHighestPageNumber, LanguageCode, SurveyStatus, VoteAcceptRejectDate, CaseID, VersionID, PdfFileName, voterSurveyStatus,
dateupdated, recordstatus, modifiedby, changereason
FROM SchemaWema.vts_tbVoter AS a
WHERE (dateupdated =
(SELECT MAX(dateupdated) AS Expr1
FROM SchemaWema.vts_tbVoter AS b
WHERE (a.VoterID = VoterID) AND (a.SurveyID = SurveyID) AND (a.CSID = CaseID) AND (a.VersionID = VersionID)))
) Voter on
Voter.CSID = Cases.CSID
AND Voter.VersionID = Cases.VersionID
Inner Join
(
SELECT DISTINCT SurveyID, DecisionSetId, FormType
FROM SchemaWema.vts_tbSurvey AS a
WHERE (dateupdated =
(SELECT MAX(dateupdated) AS Expr1
FROM SchemaWema.vts_tbSurvey AS b
WHERE (a.SurveyID = SurveyID))) AND (recordstatus <> ''D'')
) Survey on
Survey.SurveyID = Voter.SurveyID
inner Join
(
SELECT DISTINCT
VoterID, AnswerID, SectionNumber, CAST(AnswerText AS varchar(MAX)) AnswerText, SurveyID, CaseID, versionID
FROM SchemaWema.vts_tbVoterAnswers AS a
WHERE (dateupdated =
(SELECT MAX(dateupdated) AS Expr1
FROM SchemaWema.vts_tbVoterAnswers AS b
WHERE (a.VoterID = VoterID) AND (a.AnswerID = AnswerID) AND (a.SectionNumber = SectionNumber) AND (a.SurveyID = SurveyID) AND (a.CSID = CaseID) AND
(a.versionID = versionID))) AND (recordstatus <> ''D'')
)VoterAnswers on
VoterAnswers.SurveyID = Survey.SurveyID
AND VoterAnswers.CSID = Voter.CSID
AND Voter.VoterID = VoterAnswers.VoterID
AND VoterAnswers.versionID = Voter.versionID
AND VoterAnswers.SurveyID = Voter.SurveyID
FULL OUTER JOIN
(
select DISTINCT a.USERID, a.USERNAME, a.FIRSTNAME, a.LASTNAME, a.SHOWNNAME
from SchemaWema.users as a
WHERE (a.userdateupdated =
(SELECT MAX(b.userdateupdated) AS Expr1
FROM SchemaWema.users AS b
WHERE (a.userID = b.userID) ))
AND (a.RECORDSTATUS <> ''D'')
) Users on
VoterAnswers.VoterID = Users.USERID
AND Voter.VoterID = Users.USERID
inner join
(
SELECT DISTINCT AnswerID, QuestionID, AnswerText FROM SchemaWema.vts_tbAnswer AS a
WHERE (dateupdated =
(SELECT MAX(dateupdated) AS Expr1
FROM SchemaWema.vts_tbAnswer AS b
WHERE (a.AnswerID = AnswerID))) AND (recordstatus <> ''D'')
) Answer on
Answer.AnswerID = VoterAnswers.AnswerID
inner Join
(
SELECT DISTINCT QuestionID,SurveyID, QuestionText
FROM SchemaWema.vts_tbQuestion AS a
WHERE (dateupdated =
(SELECT MAX(dateupdated) AS Expr1
FROM SchemaWema.vts_tbQuestion AS b
WHERE (a.QuestionID = QuestionID))) AND (recordstatus <> ''D'')
) Question on
Answer.QuestionID = Question.QuestionID
AND Question.SurveyID = Survey.SurveyID
AND Question.SurveyID = VoterAnswers.SurveyID
inner join
(
SELECT DIStinct
[PANELID] ,[PANELNAME]
FROM [AdjudicateV3].[Adjudicate].[PROJECTPANELVIEW]
)Panel on
Panel.PANELID = Cases.PanelID
WHERE CASEs.ID = ' + @ID + ' AND Survey.DecisionSetId = '+ DeeSetId +' AND Survey.FormType = '+ @Forms +'
) AS SourceTable
PIVOT
(
MAX(AnswerText)
FOR QuestionText IN ('+@columns+')
) AS PivotTable'
可以使用动态枢轴来完成。
您要做的第一件事是构建要用于数据透视表的列。
declare @cols varchar(max)
select @cols = Coalesce(@cols + ', ', '') + '[' + q.Question + '(' + a.Question + ')]'
from Questions q
join Answers a on q.ID = a.QuestionID
这会将您想要的所有列 headers 连接成一个字符串,例如
[What is your favorite Car Color(Blue)], [What is your favorite Car Color(Red)]
将列名放在括号内很重要...
下一步是构建数据透视查询
declare @sql varchar(max)
set @sql = 'Select [User], ' + @cols + ' from (
select ua.[User], ''X'' as Chosen,
q.Question + ''('' + a.Question + '')'' Answer
from UserAnswers ua
join Answers a On ua.AnswerId = a.ID and ua.QuestionID = a.QuestionID
join Questions q on a.QuestionID = q.ID
) t
pivot (
max(Chosen)
for Answer IN (' + @cols + ')
) p'
exec(@sql)
这将创建一个包含三列用户、选择、答案的子查询。用户是用户名,选择的只是每条记录的 X,以及用于转换的答案。答案看起来像上面没有括号的列名..
接下来它旋转子查询..并选择名称和动态列..