【问题标题】:Trouble with PIVOT in SQL (Azure SQL)SQL (Azure SQL) 中的 PIVOT 问题
【发布时间】:2019-04-17 21:45:03
【问题描述】:

我需要在一行中列出调查回复。调查回复表列出了 questionID 和 ResponseID(这些是多项选择题),因此每个回复对应一行。有 12 个问题。诸如回复日期、进行调查的工作人员和进入调查的工作人员等信息保存在其他表格中。

所以,我有一个查询,可以将一项调查的回复分成 12 行。现在我需要把所有这些都放在一排。枢轴,对吧?

但我永远无法让它工作。 :-( 从这个论坛和其他论坛尝试了几种解决方案(包括 Mickey 的文档:https://docs.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-2017)。

然后我找到了这个根本不使用枢轴的解决方案,在这里:SQL Pivot Table Grouping

效果很好,但该示例只有两个问题。我们的一些调查将有超过 50 个问题,所以我猜这不会是一个非常优雅的解决方案。

所以我回到我的支点问题。

经验水平介于白痴和新手之间,所以我可能遗漏了一些明显的东西。

这是查询本身(按预期工作):

SELECT AssessmentResponses.ID, AssessmentQuestions.QuestionNumber, 
   AssessmentResponseAnswers.QuestionID,
   AssessmentAnswerChoices.AnswerChoiceNumber 
FROM (AssessmentResponses RIGHT JOIN AssessmentResponseAnswers 
   ON AssessmentResponses.ID = AssessmentResponseAnswers.AssessmentResponseID) 
   LEFT JOIN (AssessmentQuestions RIGHT JOIN AssessmentAnswerChoices 
   ON AssessmentQuestions.ID = AssessmentAnswerChoices.AssessmentQuestionID) 
   ON AssessmentResponseAnswers.AnswerChoiceID = AssessmentAnswerChoices.AnswerChoiceID 
WHERE AssessmentResponses.AssessmentID = 1 AND AssessmentResponses.RespondentID = 44;

以下是我尝试使其旋转的方法:

SELECT ID, [1A], [1B], [2A], [2B], [3A], [3B], [4A], [4B], [5A], [5B], [6A], [6B] 
FROM (
SELECT AssessmentResponses.ID, AssessmentQuestions.QuestionNumber, 
   AssessmentResponseAnswers.QuestionID,
   AssessmentAnswerChoices.AnswerChoiceNumber 
FROM (AssessmentResponses RIGHT JOIN AssessmentResponseAnswers 
   ON AssessmentResponses.ID = AssessmentResponseAnswers.AssessmentResponseID) 
   LEFT JOIN (AssessmentQuestions RIGHT JOIN AssessmentAnswerChoices 
   ON AssessmentQuestions.ID = AssessmentAnswerChoices.AssessmentQuestionID)
   ON AssessmentResponseAnswers.AnswerChoiceID = AssessmentAnswerChoices.AnswerChoiceID 
WHERE AssessmentResponses.AssessmentID = 1 AND AssessmentResponses.RespondentID = 44
) AS Src 
PIVOT
(
MAX(AnswerChoiceNumber) 
FOR QuestionNumber IN ([1A], [1B], [2A], [2B], [3A], [3B], [4A], [4B], [5A], [5B], [6A], [6B]) 
)
AS Pvt;

我希望这会给我 1 行 13 列(ID 加上十二个问题)。但它仍然给了我 12 行:13 列在那里,它只为 12 个问题中的 11 个提供空值。 (在第1行,1A有答案;在第2行,1B有答案,等等)

我错过了什么?

【问题讨论】:

  • 我认为您可以删除 azure-sql-database 标记。你的问题不是特定的。您可能会吸引其他响应者,甚至有人可能会为您编写动态 sql 语句,这将比我的回答更灵活,当然还有动态 SQL 的标准警告。

标签: sql sql-server pivot azure-sql-database


【解决方案1】:

稍微调整您的代码以摆脱子查询中的“QuestionID”。它不涉及您所依赖的内容,因此 SQL Server 会认为它是您的关键之一。

SELECT ID, [1A], [1B], [2A], [2B], [3A], [3B], [4A], [4B], [5A], [5B], [6A], [6B] 
FROM (
SELECT AssessmentResponses.ID, AssessmentQuestions.QuestionNumber, 
   AssessmentAnswerChoices.AnswerChoiceNumber 
FROM (AssessmentResponses RIGHT JOIN AssessmentResponseAnswers 
   ON AssessmentResponses.ID = AssessmentResponseAnswers.AssessmentResponseID) 
   LEFT JOIN (AssessmentQuestions RIGHT JOIN AssessmentAnswerChoices 
   ON AssessmentQuestions.ID = AssessmentAnswerChoices.AssessmentQuestionID)
   ON AssessmentResponseAnswers.AnswerChoiceID = AssessmentAnswerChoices.AnswerChoiceID 
WHERE AssessmentResponses.AssessmentID = 1 AND AssessmentResponses.RespondentID = 44
) AS Src 
PIVOT
(
MAX(AnswerChoiceNumber) 
FOR QuestionNumber IN ([1A], [1B], [2A], [2B], [3A], [3B], [4A], [4B], [5A], [5B], [6A], [6B]) 
)
AS Pvt;

我想你已经习惯了设计师。使代码更具可读性的一些技巧(上面未实现):

  • 您通常可以省略连接语句周围的括号
  • 我会重新处理您的联接,以便为每个联接语句关联一个 on 语句
  • 别名!

【讨论】:

  • 太棒了!!从您的查询版本中删除的是“QuestionID”。一旦我删除它,我就得到了我想要的结果。非常感谢!我其实不习惯这个设计师。 (别开玩笑:设计师是什么?)我正在使用 SSMS。我在连接方面遇到了困难,所以(我知道这是糟糕)我在 MS Access 中构建表,使用设计器进行查询,然后将 SQL 复制到 SSMS 中,看看它是否有效。这使我成为一个黑客,但我正在努力学习。再次感谢!
  • 我在 SSMS 中工作以添加别名、重新处理连接并省略括号。查询仍然有效。 :-) 感谢您的提示。
  • 哎呀,更改了答案叙述以反映正确的列。谢谢。很高兴它成功了。
【解决方案2】:

在我看来,这并不完全是与枢轴有关的工作。可能是这样的:

SELECT ar.ID
,(
  SELECT aac.AnswerChoiceNumber
  FROM AssessmentResponseAnswers ara, AssessmentAnswerChoices aac, AssessmentQuestions aq
  WHERE ar.ID=ara.AssessmentResponseID
  AND ara.AnswerChoiceID=aac.AnswerChoiceID
  AND aq.ID=aac.AssessmentQuestionID
  AND aq.QuestionNumber='1A'
 ) 1A
 ,(
  SELECT aac.AnswerChoiceNumber
  FROM AssessmentResponseAnswers ara, AssessmentAnswerChoices aac, AssessmentQuestions aq
  WHERE ar.ID=ara.AssessmentResponseID
  AND ara.AnswerChoiceID=aac.AnswerChoiceID
  AND aq.ID=aac.AssessmentQuestionID
  AND aq.QuestionNumber='1B'
 ) 1B
, (...)
FROM AssessmentResponses ar
WHERE ar.AssessmentID=1 
AND ar.RespondentID=44

我在您使用连接时遇到问题,但我试图弄清楚 - 也许它是正确的。

【讨论】:

  • Bartosz,你为什么不填写省略号作为练习。然后想象一下 OP 的要求,即某些调查将有 50 多个问题。然后想象一下对一个基表名称进行更改,并且必须在扩展查询中实现这个简单的更改。
  • 感谢您的回复!对不起我的加入;他们确实是垃圾。我尝试了 1A 和 1B 的代码并且它有效(但我必须在它们周围加上方括号,如下所示:) [1A])。但是,对于较大的调查,必须编写所有这些代码会有点多。上面带有 pivot 语句的解决方案为我解决了问题。
猜你喜欢
  • 2020-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多