Tout d'abord, j'ai essayé de chercher une réponse, mais honnêtement, je ne sais pas exactement quoi rechercher ...

J'ai un ensemble de données que j'ai importé dans SQL Server et j'ai besoin d'en obtenir des données utilisables. Voici le format ...

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

Et ainsi de suite ... Ce dont j'ai besoin, c'est de pouvoir renvoyer un décompte des différentes réponses de Jane Doe pour la question 1, la question 2, etc. Je dois revenir pour la question 1 de Jane, il y a 2 d'accord et 1 pas d'accord. J'en ai besoin pour plusieurs professeurs.

J'ai essayé d'utiliser GROUP BY mais je ne dois pas faire quelque chose de bien. J'ai essayé des variantes de:

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

Merci de votre aide!

MODIFIER

Donc, c'est la requête qui a fini par me procurer ce dont j'avais besoin. Je crois que mes données devaient être non pivotées pour rendre cela beaucoup plus facile. C'est la requête qui m'a permis d'obtenir ce que je cherchais ...

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
0
Jeff Green 24 janv. 2017 à 22:22

5 réponses

Meilleure réponse

Vous pouvez faire quelque chose comme ceci pour obtenir le décompte de toutes les options par question.

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
0
JamieD77 24 janv. 2017 à 19:50

Vous pouvez utiliser apply() pour décompresser d'abord votre tableau au lieu de chaîner union all.

Configuration du test: 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);

Requete:

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

Production:

+----------+----------+-------------------+-------------+
| 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 |
+----------+----------+-------------------+-------------+
0
SqlZim 24 janv. 2017 à 19:52

Vous ne savez pas ce que vous voulez dans le résultat final, mais cette méthodologie devrait vous donner un chemin clair à suivre et un résultat facilement compréhensible.

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

En faisant cela, vous créerez un enregistrement unique pour chaque enseignant et pourrez ensuite définir des groupes pour chaque sortie. Si vous voulez simplement savoir combien de fois ils ont répondu à la question, vous pouvez utiliser des décomptes, si vous voulez compter des conditions.

0
Franz Stoneking 24 janv. 2017 à 19:45

Il semble qu'une seule requête comme suggéré dans certains commentaires ne vous donnera pas ce que vous voulez. Ma suggestion serait d'aller pour trois requêtes distinctes comme

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

Consultez ici un exemple de travail: http://rextester.com/CTA10481

0
cars10m 24 janv. 2017 à 20:10

Vos données ne sont pas normalisées (chaque réponse à une question doit être sa propre ligne, pas une colonne). Vous devrez annuler le pivotement des données d'une manière ou d'une autre si vous souhaitez effectuer de véritables requêtes relationnelles sur les données.

Nous pourrions utiliser un UNPIVOT explicite mais je pense que l'utilisation d'un UNION montre clairement ce qui se passe:

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
  • J'utilise un UNION ALL pour améliorer les performances car nous n'avons pas besoin d'un véritable résultat set-union (c'est-à-dire suppression des doublons).
  • Répétez le SELECT pour chaque colonne de question supplémentaire.

Cela transformera vos données en quelque chose comme ceci:

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

Ensuite, vous pouvez exécuter des requêtes relationnelles sur ces données:

Ce dont j'ai besoin est de pouvoir renvoyer un décompte des différentes réponses de Jane Doe pour la question 1

Ceci est fait comme ceci:

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

Ou pour l'obtenir pour toutes les questions:

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

La requête complète:

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
0
Dai 24 janv. 2017 à 19:40