Count com group by
Colegas, tenho um cadastro onde os alunos votaram sobre alguns cursos ministrados, preciso então de imprimir o resultado.
Tabela de gabarito tenho:
ID_CURSO
ID_PERIODO
R1
R2
R3
R4
Os campos R1,R2,R3,R4 são os campos tipo char(1) que o aluno responde sobre determinada pergunta: R(ruim)B(bom)M(médio).
Preciso num SQL agrupar essas resposta me dando o somatório de cada resposta.
Tipo assim:
CURSO 1 PERIODO 5 BOM MEDIO RUIM
PERGUNTA1(R1)100 30 40
PERGUNTA2(R2)30 50 48
PERGUNTA3(R3)32 50 29
PERGUNTA4(R4)49 10 28
Nesse exemplo funciona:
SELECT G.ID_CURSO,G.ID_PERIODO,COUNT(R1)as BOM
FROM gabarito G
WHERE
G.R1 = ´B´
GROUP by
G.ID_CURSO,G.ID_PERIODO
Funciona beleza
Mas como são muitas respostas diferentes nesse outro exemplo o resultado não bate.
SELECT G.ID_CURSO,G.ID_PERIODO,
(SELECT COUNT(R1)FROM GABARITO WHERE R1 = ´B´)AS BOM,
(SELECT COUNT(R1)FROM GABARITO WHERE R1 = ´R´)AS RUIM,
(SELECT COUNT(R1)FROM GABARITO WHERE R1 = ´M´)AS MEDIO,
(SELECT COUNT(R2)FROM GABARITO WHERE R2 = ´B´)AS BOM,
(SELECT COUNT(R2)FROM GABARITO WHERE R2 = ´R´)AS RUIM,
(SELECT COUNT(R2)FROM GABARITO WHERE R2 = ´M´)AS MEDIO
FROM GABARITO G
GROUP by
G.ID_CURSO,G.ID_PERIODO
Além de repetir o valor,a conta não bate.
O que estou fazendo de errado?
Grato:
Jose Luiz
Tabela de gabarito tenho:
ID_CURSO
ID_PERIODO
R1
R2
R3
R4
Os campos R1,R2,R3,R4 são os campos tipo char(1) que o aluno responde sobre determinada pergunta: R(ruim)B(bom)M(médio).
Preciso num SQL agrupar essas resposta me dando o somatório de cada resposta.
Tipo assim:
CURSO 1 PERIODO 5 BOM MEDIO RUIM
PERGUNTA1(R1)100 30 40
PERGUNTA2(R2)30 50 48
PERGUNTA3(R3)32 50 29
PERGUNTA4(R4)49 10 28
Nesse exemplo funciona:
SELECT G.ID_CURSO,G.ID_PERIODO,COUNT(R1)as BOM
FROM gabarito G
WHERE
G.R1 = ´B´
GROUP by
G.ID_CURSO,G.ID_PERIODO
Funciona beleza
Mas como são muitas respostas diferentes nesse outro exemplo o resultado não bate.
SELECT G.ID_CURSO,G.ID_PERIODO,
(SELECT COUNT(R1)FROM GABARITO WHERE R1 = ´B´)AS BOM,
(SELECT COUNT(R1)FROM GABARITO WHERE R1 = ´R´)AS RUIM,
(SELECT COUNT(R1)FROM GABARITO WHERE R1 = ´M´)AS MEDIO,
(SELECT COUNT(R2)FROM GABARITO WHERE R2 = ´B´)AS BOM,
(SELECT COUNT(R2)FROM GABARITO WHERE R2 = ´R´)AS RUIM,
(SELECT COUNT(R2)FROM GABARITO WHERE R2 = ´M´)AS MEDIO
FROM GABARITO G
GROUP by
G.ID_CURSO,G.ID_PERIODO
Além de repetir o valor,a conta não bate.
O que estou fazendo de errado?
Grato:
Jose Luiz
Jose Luiz
Curtidas 0
Respostas
Emerson Nascimento
28/07/2009
você precisa filtrar, na subselect, o curso e período, senão não bate:
ou, para evitar o uso de subselects e deixar a instrução mais limpa e legível, e ainda obter melhor performance, use SUM() em conjunto com CASE:
obviamente o funcionamento da instrução vai depender do banco de dados utilizado.
SELECT G.ID_CURSO, G.ID_PERIODO, (SELECT COUNT(G2.R1) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R1 = ´B´) AS R1_BOM, (SELECT COUNT(G2.R1) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R1 = ´R´) AS R1_RUIM, (SELECT COUNT(G2.R1) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R1 = ´M´) AS R1_MEDIO, (SELECT COUNT(G2.R2) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R2 = ´B´) AS R2_BOM, (SELECT COUNT(G2.R2) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R2 = ´R´) AS R2_RUIM, (SELECT COUNT(G2.R2) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R2 = ´M´) AS R2_MEDIO, (SELECT COUNT(G2.R2) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R3 = ´B´) AS R3_BOM, (SELECT COUNT(G2.R2) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R3 = ´R´) AS R3_RUIM, (SELECT COUNT(G2.R2) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R3 = ´M´) AS R3_MEDIO, (SELECT COUNT(G2.R2) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R4 = ´B´) AS R4_BOM, (SELECT COUNT(G2.R2) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R4 = ´R´) AS R4_RUIM, (SELECT COUNT(G2.R2) FROM GABARITO G2 WHERE G2.ID_CURSO=G.ID_CURSO AND G2.ID_PERIODO=G.ID_PERIODO AND G2.R4 = ´M´) AS R4_MEDIO FROM GABARITO G GROUP by G.ID_CURSO,G.ID_PERIODO
ou, para evitar o uso de subselects e deixar a instrução mais limpa e legível, e ainda obter melhor performance, use SUM() em conjunto com CASE:
SELECT ID_CURSO, ID_PERIODO, SUM(CASE WHEN R1 = ´B´ THEN 1 ELSE 0 END) AS R1_BOM, SUM(CASE WHEN R1 = ´M´ THEN 1 ELSE 0 END) AS R1_MEDIO, SUM(CASE WHEN R1 = ´R´ THEN 1 ELSE 0 END) AS R1_RUIM, SUM(CASE WHEN R2 = ´B´ THEN 1 ELSE 0 END) AS R2_BOM, SUM(CASE WHEN R2 = ´M´ THEN 1 ELSE 0 END) AS R2_MEDIO, SUM(CASE WHEN R2 = ´R´ THEN 1 ELSE 0 END) AS R2_RUIM, SUM(CASE WHEN R3 = ´B´ THEN 1 ELSE 0 END) AS R3_BOM, SUM(CASE WHEN R3 = ´M´ THEN 1 ELSE 0 END) AS R3_MEDIO, SUM(CASE WHEN R3 = ´R´ THEN 1 ELSE 0 END) AS R3_RUIM, SUM(CASE WHEN R4 = ´B´ THEN 1 ELSE 0 END) AS R4_BOM, SUM(CASE WHEN R4 = ´M´ THEN 1 ELSE 0 END) AS R4_MEDIO, SUM(CASE WHEN R4 = ´R´ THEN 1 ELSE 0 END) AS R4_RUIM FROM GABARITO GROUP BY ID_CURSO, ID_PERIODO
obviamente o funcionamento da instrução vai depender do banco de dados utilizado.
GOSTEI 0
Nasguone
28/07/2009
Baseando-se que vc esteja usando o MSSQL vc poderia usar assim, que ja te retorna o total por respostas:
select A.ID_curso
,R1 =(SELECT COUNT(case when A.Apont_Status = ´R´ then 1 end))
,R2 =(SELECT COUNT(case when A.Apont_Status = ´B´ then 1 end))
,R3 =(SELECT COUNT(case when A.Apont_Status = ´M´ then 1 end))
,R4 =(SELECT COUNT(case when A.Apont_Status = ´O´ then 1 end))
, COUNT(*) AS´TOTAL GERAL´
FROM TABELA_DAS_RESPOSTA A
where
A.ID_PERIODO =´PERIODO´
group by A.ID_CURSO WITH ROLLUP
Order by A.ID_CURSO DESC
Espero que te ajude
E.C.S
select A.ID_curso
,R1 =(SELECT COUNT(case when A.Apont_Status = ´R´ then 1 end))
,R2 =(SELECT COUNT(case when A.Apont_Status = ´B´ then 1 end))
,R3 =(SELECT COUNT(case when A.Apont_Status = ´M´ then 1 end))
,R4 =(SELECT COUNT(case when A.Apont_Status = ´O´ then 1 end))
, COUNT(*) AS´TOTAL GERAL´
FROM TABELA_DAS_RESPOSTA A
where
A.ID_PERIODO =´PERIODO´
group by A.ID_CURSO WITH ROLLUP
Order by A.ID_CURSO DESC
Espero que te ajude
E.C.S
GOSTEI 0
Nasguone
28/07/2009
Baseando-se que vc esteja usando o MSSQL vc poderia usar assim, que ja te retorna o total por respostas:
select A.ID_curso
,R1 =(SELECT COUNT(case when A.Apont_Status = ´R´ then 1 end))
,R2 =(SELECT COUNT(case when A.Apont_Status = ´B´ then 1 end))
,R3 =(SELECT COUNT(case when A.Apont_Status = ´M´ then 1 end))
,R4 =(SELECT COUNT(case when A.Apont_Status = ´O´ then 1 end))
, COUNT(*) AS´TOTAL GERAL´
FROM TABELA_DAS_RESPOSTA A
where
A.ID_PERIODO =´PERIODO´
group by A.ID_CURSO WITH ROLLUP
Order by A.ID_CURSO DESC
Espero que te ajude
E.C.S
select A.ID_curso
,R1 =(SELECT COUNT(case when A.Apont_Status = ´R´ then 1 end))
,R2 =(SELECT COUNT(case when A.Apont_Status = ´B´ then 1 end))
,R3 =(SELECT COUNT(case when A.Apont_Status = ´M´ then 1 end))
,R4 =(SELECT COUNT(case when A.Apont_Status = ´O´ then 1 end))
, COUNT(*) AS´TOTAL GERAL´
FROM TABELA_DAS_RESPOSTA A
where
A.ID_PERIODO =´PERIODO´
group by A.ID_CURSO WITH ROLLUP
Order by A.ID_CURSO DESC
Espero que te ajude
E.C.S
GOSTEI 0