Fórum Count com group by #372862

28/07/2009

0

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


Jose Luiz

Jose Luiz

Responder

Posts

29/07/2009

Emerson Nascimento

você precisa filtrar, na subselect, o curso e período, senão não bate:
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.


Responder

Gostei + 0

31/07/2009

Nasguone

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


Responder

Gostei + 0

31/07/2009

Nasguone

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


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar