SQL Query用于解析调查结果

时间:2017-01-24 19:22:57

标签: sql sql-server sql-server-2014

首先,我试图寻找答案,但说实话,我并不确切知道要搜索的内容......

我有一个导入SQL Server的数据集,需要从中获取可用数据。这是格式......

Teacher     Period    Question1    Question2    Question3
Jane Doe    1         Agree        Agree        Strongly Agree
Jane Doe    2         Disagree     Agree        Agree
John Doe    2         Agree        Disagree     Agree
John Doe    4         Disagree     Agree        Strongly Disagree
Jane Doe    3         Agree        Agree        Agree

依旧...... 我需要的是能够返回Jane Doe对Question1,Question2等的不同答案的计数。我需要返回Jane的问题1,有2个同意和1个不同意。我需要多个老师这个。

我尝试过使用GROUP BY,但我不能做正确的事情。 我尝试过各种变体:

SELECT Teacher, COUNT(Q1) AS Q1Result, COUNT(Q2) AS Q2Result
FROM Survey
GROUP BY Teacher, Q1, Q2

感谢您的帮助!

修改

所以,这是最终得到我需要的查询。我的数据需要不透明,我相信这样做会更容易。这个问题让我得到了我想要的东西......

SELECT s.Teacher,
       q.Question,
       COUNT(CASE WHEN val = 'Strongly Agree' THEN 1 END) StronglyAgreeCount,
       COUNT(CASE WHEN val = 'Agree' THEN 1 END) AgreeCount,
       COUNT(CASE WHEN val = 'Neutral' THEN 1 END) NeutralCount,
       COUNT(CASE WHEN val = 'Disagree' THEN 1 END) DisagreeCount,
       COUNT(CASE WHEN val = 'Strongly Disagree' THEN 1 END)     StronglyDisagreeCount
FROM   PCSSSurvey s 
       CROSS APPLY (VALUES(s.Q1, 'Question01'),(s.Q2, 'Question02'),(s.Q3, 'Question03'),(s.Q4, 'Question04'),(s.Q5, 'Question05'),(s.Q6, 'Question06'),(s.Q7, 'Question07'),(s.Q8, 'Question08'),(s.Q9, 'Question09'),(s.Q10, 'Question10'),(s.Q11, 'Question11'),(s.Q12, 'Question12'),(s.Q13, 'Question13')) q(val,question)
GROUP BY s.Teacher, q.Question
ORDER BY s.Teacher, q.Question

5 个答案:

答案 0 :(得分:0)

您的数据未规范化(每个问题响应应该是自己的行,而不是列)。如果要对数据进行真正的关系查询,则需要以某种方式对数据进行取消。

我们可以使用明确的UNPIVOT,但我认为使用UNION可以清楚地说明发生了什么:

SELECT
    Teacher, Period, 'Q1' AS Question, Question1 AS Response
FROM
    Survey

UNION ALL

SELECT
    Teacher, Period, 'Q2' AS Question, Question2 AS Response
FROM
    Survey

UNION ALL

SELECT
    Teacher, Period, 'Q3' AS Question, Question3 AS Response
FROM
    Survey
  • 我使用UNION ALL来提高性能,因为我们不需要真正的set-union结果(即重复删除)。
  • 对每个其他问题列重复SELECT

这会将您的数据转换为以下内容:

Teacher     Period    Question    Response
Jane Doe    1         Q1          Agree
Jane Doe    1         Q2          Agree
Jane Doe    1         Q3          Strongly Agree
Jane Doe    2         Q1          Disagree
Jane Doe    2         Q2          Agree
Jane Doe    2         Q3          Agree
... -- and so on

然后,您可以对此数据运行关系查询:

  

我需要的是能够返回Jane Doe对问题1的不同答案的计数

这样做是这样的:

SELECT
    Teacher,
    COUNT( DISTINCT Response ) AS DifferentAnswerCount
FROM
    /* inner query */
WHERE
    Question = 'Q1'
GROUP BY
    Teacher

或者为了解决所有问题:

SELECT
    Teacher,
    Question,
    COUNT( DISTINCT Response ) AS DifferentAnswerCount
FROM
    /* inner query */
GROUP BY
    Teacher,
    Question

完整查询:

SELECT
    Teacher,
    Question,
    COUNT( DISTINCT Response ) AS DifferentAnswerCount
FROM
    (
        SELECT
            Teacher, Period, 'Q1' AS Question, Question1 AS Response
        FROM
            Survey

        UNION ALL

        SELECT
            Teacher, Period, 'Q2' AS Question, Question2 AS Response
        FROM
            Survey

        UNION ALL

        SELECT
            Teacher, Period, 'Q3' AS Question, Question3 AS Response
        FROM
            Survey
    )
WHERE
    Question = 'Q1'
GROUP BY
    Teacher,
    Question

答案 1 :(得分:0)

不确定您在最终输出中的目的是什么,但这种方法应该为您提供明确的跟踪路径和易于理解的输出。

SELECT 
    Teacher 
    ,COUNT(CASE WHEN Q1 IN ('Agree','Strongly Agree') THEN 1 ELSE 0 END) AS 'Q1-Agree'
    ,COUNT(CASE WHEN Q1 IN ('Disagree','Strongly Disagree') THEN 1 ELSE 0 END) AS 'Q1-Disagree'
    ...
FROM
    input
GROUP BY 
    Teacher

通过这样做,您将为每位教师创建一个唯一的记录,然后可以为每个输出定义组。 如果您只想知道他们回答问题的次数,您可以使用计数,如果您想计算条件。

答案 2 :(得分:0)

你可以做这样的事情来获得每个问题的所有选项的计数。

SELECT s.Teacher,
       q.Question,
       COUNT(CASE WHEN val = 'Agree' THEN 1 END) AgreeCount,
       COUNT(CASE WHEN val = 'Strongly Agree' THEN 1 END) StronglyAgreeCount,
       COUNT(CASE WHEN val = 'Disagree' THEN 1 END) DisagreeCount,
       COUNT(CASE WHEN val = 'Strongly Disagree' THEN 1 END) StronglyDisagreeCount
FROM   Survey s 
       CROSS APPLY (VALUES(s.Question1, 'Question1'),(s.Question2, 'Question2'),(s.Question3, 'Question3')) q(val,question)
GROUP BY s.Teacher, q.Question
ORDER BY s.Teacher, q.Question

ouput:
Teacher  Question  AgreeCount  StronglyAgreeCount DisagreeCount StronglyDisagreeCount
-------- --------- ----------- ------------------ ------------- ---------------------
Jane Doe Question1 2           0                  1             0
Jane Doe Question2 3           0                  0             0
Jane Doe Question3 2           1                  0             0
John Doe Question1 1           0                  1             0
John Doe Question2 1           0                  1             0
John Doe Question3 1           0                  0             1

答案 3 :(得分:0)

您可以先使用apply()展开桌面,而不是将union all链接起来。

测试设置:http://rextester.com/VGESS44812

create table t (
    Teacher varchar(32)
  , Period int
  , Question1 varchar(32)
  , Question2 varchar(32)
  , Question3 varchar(32)
  );
insert into t  (Teacher,Period,Question1,Question2,Question3) values
 ('Jane Doe',1,'Agree','Agree','Strongly Agree')
,('Jane Doe',2,'Disagree','Agree','Agree')
,('John Doe',2,'Agree','Disagree','Agree')
,('John Doe',4,'Disagree','Agree','Strongly Disagree')
,('Jane Doe',3,'Agree','Agree','Agree')
,('Zim',0,'<3','apply()',null);

查询:

select 
    Teacher
  , Question
  , Answer
  , AnswerCount=count(*)
  from t
    outer apply (
      values (1,Question1),(2,Question2),(3,Question3)
    ) as x (Question,Answer)
  group by Teacher, Question, Answer

输出:

+----------+----------+-------------------+-------------+
| Teacher  | Question |      Answer       | AnswerCount |
+----------+----------+-------------------+-------------+
| Jane Doe |        1 | Agree             |           2 |
| Jane Doe |        1 | Disagree          |           1 |
| Jane Doe |        2 | Agree             |           3 |
| Jane Doe |        3 | Agree             |           2 |
| Jane Doe |        3 | Strongly Agree    |           1 |
| John Doe |        1 | Agree             |           1 |
| John Doe |        1 | Disagree          |           1 |
| John Doe |        2 | Agree             |           1 |
| John Doe |        2 | Disagree          |           1 |
| John Doe |        3 | Agree             |           1 |
| John Doe |        3 | Strongly Disagree |           1 |
| Zim      |        1 | <3                |           1 |
| Zim      |        2 | apply()           |           1 |
| Zim      |        3 | NULL              |           1 |
+----------+----------+-------------------+-------------+

答案 4 :(得分:0)

似乎某些评论中建议的单个查询无法满足您的需求。我的建议是进行三个单独的查询,如

select Teacher, Question1, count(*) cnt from tblx group by Teacher, Question1;
select Teacher, Question2, count(*) cnt from tblx group by Teacher, Question2;
select Teacher, Question3, count(*) cnt from tblx group by Teacher, Question3

请参阅此处查看工作示例:http://rextester.com/CTA10481

相关问题