none
ajuda com select RRS feed

  • Pergunta

  • preciso de ajuda com esse select..

    preciso que independente de ter notar lançadas ou não, o nome dos alunos apareçam na tabela.. obedecendo os três criterios..

    acontece que do jeito que fiz, não tá dando certo.. ele não está obedecendo o WHERE.. os resultados não vem correto..

     

    SELECT A.AT_CDALUNO, A.AT_NOME 
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN N.AT_NOTA ELSE '0' END) AS Trabalhos
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Parcial Um' THEN N.AT_NOTA ELSE '0' END) AS Prova_Parcial_Um
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Parcial Dois' THEN N.AT_NOTA ELSE '0' END) AS Prova_Parcial_Dois
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Final' THEN N.AT_NOTA ELSE '0' END) AS Prova_Final
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN N.AT_NOTA ELSE '0' END) AS Trabalhos 
    FROM TBETAPA AS E, TBALUNO AS A 
    INNER JOIN tbinseriraluno AS T ON T.AT_CDALUNO = A.AT_CDALUNO 
    INNER JOIN TBTURMA AS TU ON TU.AT_CDTURMA = T.AT_CDTURMA 
    FULL OUTER JOIN TBNOTA AS N ON N.AT_CDALUNO = A.AT_CDALUNO 
    LEFT OUTER JOIN TBAVALIACAO AS AV ON AV.AT_CDAVAL = N.AT_CDAVALIACAO 
    FULL OUTER JOIN TBINSERIRDISCIPLINA AS D ON D.AT_CDTURMA = TU.AT_CDTURMA 
    RIGHT JOIN TBDISCIPLINA AS DI ON DI.AT_CDDISCIP = D.AT_CDDISCIPLINA
     
    WHERE T.AT_CDTURMA = 1 AND DI.AT_CDDISCIP = 10 AND E.AT_CDETAPA = 1 
    GROUP BY A.AT_NOME, A.AT_CDALUNO

    domingo, 11 de setembro de 2011 22:03

Respostas

  • Desculpe mas discordo um pouco quando você diz que está errado com o uso do 0.

    Basicamente se a nota não é do tipo de avaliação, disciplina ou etapa desejados soma-se 0.

    De qualquer forma, segue outra sugestão:

    SELECT 
        a.at_cdaluno, 
        a.at_nome,
        coalesce(tr.at_nota, 0) as Trabalhos 
    from tbturma as t   
    join tbinseriraluno as ta on ta.at_cdturma = t.at_cdturma  
    join tbaluno as a on a.at_cdaluno = ta.at_cdaluno  
    left join
        (select n.at_cdaluno, sum(n.at_nota) as at_nota
         from tbnota as n
         join tbavaliacao as av on av.at_cdaval = n.at_cdavaliacao
         where 
             (AV.AT_NMAVALIAC = 'Trabalhos') AND
             (N.AT_CDDISCIPLINA = '9') and 
             (N.AT_CDETAPA = '2')
         group by
             n.at_cdaluno) as tr on tr.at_cdaluno = a.at_cdaluno
    where t.at_cdturma = 1  
    order by a.at_nome 

    Espero que seja útil.

     


    Assinatura: Salas comerciais em Guarulhos

    • Editado gapimex segunda-feira, 19 de setembro de 2011 05:07
    • Editado Eder Costa sexta-feira, 23 de setembro de 2011 13:36 Ativação do código
    • Sugerido como Resposta Eder Costa sexta-feira, 23 de setembro de 2011 13:36
    • Marcado como Resposta Eder Costa segunda-feira, 26 de setembro de 2011 17:20
    segunda-feira, 19 de setembro de 2011 04:39

Todas as Respostas

  • Kyrla,

    Até onde entendi da consulta o relacionamento entre aluno e nota não é feito da maneira esperada por vc.

    Se vc tentar fazer um LEFT JOIN entre aluno e nota, tipo:

    SELECT  ....

    FROM TBALUNO AS A  left outer join TBNOTA AS N ON N.AT_CDALUNO = A.AT_CDALUNO 

    ......

    WHERE......

     

    Att.,

     


    Marco Antônio Pinheiro / MCTS - MCC http://marcoantoniopinheiro.blogspot.com
    segunda-feira, 12 de setembro de 2011 11:10
  • eu até sei na teoria o funcionamento desses JOINS.. porém na prática eu não consigo aplicar muito bem.. e certamente o erro está na utilização deles.. na ordem sei lá..

    sobre o seu entendimento em relação a consulta.. estou tentando criar um select que vai me trazer os as notas dos alunos para as avaliações, de X turma, Y etapa e Z disciplina.. entretanto.. o nome dos alunos tem que ser listado só do fato dele estar na turma que estou pesquisando, sem que necessariamente tenham notas lançadas para ele naquela disciplina ou etapa..

     

    irei tentar trocar de FULL pra LEFT, e lhe retorno.. obrigada por enquanto..

    segunda-feira, 12 de setembro de 2011 12:46
  • Realmente seus relacionamentos estão estranhos. Vá fazendo por partes.

    Tb é importante entender o conceito de cada uma.

    Se ainda não resolver, mande a nova consulta.

     

    Att.,


    Marco Antônio Pinheiro / MCTS - MCC http://marcoantoniopinheiro.blogspot.com
    segunda-feira, 12 de setembro de 2011 14:04
  • acho que consegui visualizar parte do problema.. ocorre que minha tabela Etapa ela só se relaciona com a tabela de avaliação, e fazendo esse monte de relacionamento só tenho a etapa nas tabelas quando lanço a nota, então quando faço esses relacionamentos e peço pra trazer as informações que obedeça também a etapa, não funciona, pois defino uma condição onde num primeiro momento, quando a tabela não está populada, não existe etapa em nenhuma tabela que seja ela mesma..

    só que não justifica eu leva o código da etapa como chave estrangeira para as demais tabelas, uma vez que se cadastrada uma turma por exemplo ela faz parte de todas as etapas..

    preciso que a etapa seja considerada só pra separar as notas do semestre.. tem alguma dica?

    terça-feira, 13 de setembro de 2011 00:43
  • preciso de ajuda com o SELECT abaixo..

    Quando faço o select, preciso que seja exibido as notas dos alunos no formato Aluno Avaliações, considerando que alunos e avaliações são colunas... Porém, quero que os alunos sejam exibidos mesmo que não tenham notas lançadas para a disciplina X e etapa Y, afinal, só o fato dele ser da turma que estou pesquisando, ele deve aparecer no meu resultado. Só que quando eu coloco os critérios disciplina e etapa, não são mostrados os alunos que estão sem notas na disciplina e na etapa, ou um ou outro...

    Meu select no momento está assim:

    select t.at_nmturma, td.at_cddisciplina, a.at_nome, n.at_nota, e.at_cdetapa
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN N.AT_NOTA ELSE '0' END) AS Trabalhos
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Parcial Um' THEN N.AT_NOTA ELSE '0' END) AS Prova_Parcial_Um
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Parcial Dois' THEN N.AT_NOTA ELSE '0' END) AS Prova_Parcial_Dois
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Final' THEN N.AT_NOTA ELSE '0' END) AS Prova_Final
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN N.AT_NOTA ELSE '0' END) AS Trabalhos
    from tbturma as t
    left join tbinserirdisciplina as td on td.at_cdturma = t.at_cdturma
    left join tbinseriraluno as ta on ta.at_cdturma = t.at_cdturma
    left join tbaluno as a on a.at_cdaluno = ta.at_cdaluno
    left join tbnota as n on n.at_cdaluno = a.at_cdaluno
    left join tbavaliacao as av on av.at_cdaval = n.at_cdavaliacao
    left join tbetapa as e on e.at_cdetapa = av.at_cdetapa
    where t.at_cdturma = 9 and e.at_cdetapa = 1
    group by t.at_nmturma, td.at_cddisciplina, a.at_nome, n.at_nota, e.at_cdetapa


    e abaixo mostro a vocês as tabelas que estariam envolvidas nesta consulta, mas só com as chaves estrangeiras pra vc ter uma melhor noção.. Só pra esclarecer, as avaliações cadastradas serão padrão da escola, e todas as disciplinas em todas as etapas respeitarão.. Por isso na tabela avaliação eu coloquei como chave estrangeira só cdetapa.. E as turmas, a mesma ideia, uma vez adicionada, ela vai até o final de todas as etapas..

    tbaluno
      at_cdaluno integer NOT NULL

    tbavaliacao
      at_cdaval integer NOT NULL,
      at_nmavaliac character varying NOT NULL,
      at_cdetapa integer,
      at_valor numeric,

    tbdisciplina
      at_cddiscip integer NOT NULL,

    tbetapa
      at_cdetapa integer NOT NULL,

    tbinseriraluno // nessa tabela eu adiciono o aluno a uma turma
      at_cddadosturma integer NOT NULL,
      at_cdaluno integer,
      at_cdturma integer,

    tbinserirdisciplina // nessa tabela adiciono o professor a uma turma e informo qual será a disciplina dele na turma
      at_cddadosturma integer NOT NULL,
      at_cdprofessor integer,
      at_cddisciplina integer,
      at_cdturma integer,

    tbnota
      at_nota numeric,
      at_cdnota integer NOT NULL,
      at_cdaluno integer,
      at_cddisciplina integer,
      at_cdetapa integer,
      at_cdavaliacao integer,
      at_cdturma integer,

    tbturma
      at_cdturma integer NOT NULL,
      at_nmturma character varying NOT NULL,


    Pela lógica da minha estrutura, e de acordo com o meu select, acredito que ele esteja retornando corretamente.. porém, se for o caso.. precisaria de uma alternativa pro select, ou se necessário mexer no banco..

    Se alguém puder me ajudar..

    quarta-feira, 14 de setembro de 2011 12:48
  • Não sei se entendi corretamente, mas experimente desta forma:

     

    select t.at_nmturma, td.at_cddisciplina, a.at_nome, n.at_nota, e.at_cdetapa 
     , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN N.AT_NOTA ELSE '0' END) AS Trabalhos 
     , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Parcial Um' THEN N.AT_NOTA ELSE '0' END) AS Prova_Parcial_Um 
     , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Parcial Dois' THEN N.AT_NOTA ELSE '0' END) AS Prova_Parcial_Dois 
     , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Final' THEN N.AT_NOTA ELSE '0' END) AS Prova_Final 
     , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN N.AT_NOTA ELSE '0' END) AS Trabalhos 
     from tbturma as t 
     join tbinseriraluno as ta on ta.at_cdturma = t.at_cdturma 
     join tbaluno as a on a.at_cdaluno = ta.at_cdaluno 
     left join tbinserirdisciplina as td on td.at_cdturma = t.at_cdturma 
     left join tbnota as n on n.at_cdaluno = a.at_cdaluno 
     left join tbavaliacao as av on av.at_cdaval = n.at_cdavaliacao 
     left join tbetapa as e on e.at_cdetapa = av.at_cdetapa 
     where (t.at_cdturma = 9) and ( (e.at_cdetapa = 1) or (e.at_cdetapa is null) )
     group by t.at_nmturma, td.at_cddisciplina, a.at_nome, n.at_nota, e.at_cdetapa
    

    A alteração principal seria no where.

     

    Espero que seja útil.

     


    Assinatura: Salas comerciais em Guarulhos
    quarta-feira, 14 de setembro de 2011 13:12
  • Kyrla,

    A ideia é essa. Para vc relacionar a tabela de ETAPA mesmo não tendo registros nele, é usando um LEFT ou RIGHT JOIN.

    Pelo que entendi, ficaria + ou - assim:

    SELECT A.AT_CDALUNO, A.AT_NOME 
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN N.AT_NOTA ELSE '0' END) AS Trabalhos
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Parcial Um' THEN N.AT_NOTA ELSE '0' END) AS Prova_Parcial_Um
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Parcial Dois' THEN N.AT_NOTA ELSE '0' END) AS Prova_Parcial_Dois
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Prova Final' THEN N.AT_NOTA ELSE '0' END) AS Prova_Final
    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN N.AT_NOTA ELSE '0' END) AS Trabalhos 
    FROM TBALUNO AS A 
    INNER JOIN tbinseriraluno AS T ON T.AT_CDALUNO = A.AT_CDALUNO 
    INNER JOIN TBTURMA AS TU ON TU.AT_CDTURMA = T.AT_CDTURMA 
    INNER JOIN TBNOTA AS N ON N.AT_CDALUNO = A.AT_CDALUNO 
    LEFT JOIN TBAVALIACAO AS AV ON AV.AT_CDAVAL = N.AT_CDAVALIACAO

    LEFT JOIN TBETAPA AS E ON (relacionamento entre etapa e avaliação)
    RIGHT JOIN TBDISCIPLINA AS DI ON DI.AT_CDDISCIP = D.AT_CDDISCIPLINA
    GROUP BY A.AT_NOME, A.AT_CDALUNO

    Faça sem o WHERE apenas para ver se os registros serão mostrados.

    Um dica seria fazer por partes. Faça a consulta tabela a tabela, assim vc saberá em qual relacionamento está o problema.

     

    Att.,


    Marco Antônio Pinheiro / MCTS - MCC http://marcoantoniopinheiro.blogspot.com
    quarta-feira, 14 de setembro de 2011 15:27
  • eu já fiz os relacionamentos por parte.. corre tudo bem até o momento que defino a clausula where pedindo que seja exibido só o que está na disciplina X e etapa Y.. se eu retirar essas duas condições, exibi corretamente.. todos os alunos que estão na turma..

    me sugeriram fazer a consulta com o where assim:

    where (t.at_cdturma = 9) and ( (e.at_cdetapa = 1) or (e.at_cdetapa is null) )

    outa pessoa falou pra eu fazer outro case dentro do select..

    , SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN WHEN N.AT_VALOR IS NULL THEN N.AT_NOTA ELSE '0' END) AS Trabalhos

    tenho que testa essas duas informações..

    acredito que a estrutura do meu select está correta.. que o problema é justamente o where..

    testarei também sua ajuda.. só que os testes posso fazer só de noite.. passa por aqui mais tarde..

    abraços. 

     

    quarta-feira, 14 de setembro de 2011 16:35
  • não deu muito certo essa opção.. por exemplo..

    fiz um teste informando os alunos de uma turma que tem alunos e notas já cadastras, com etapa e disciplina..

    ao informar na consulta o código da etapa e da disciplina que o pessoal tem nota, traz todo mundo inclusive os que não tem..

    porém, se eu coloca a disciplina ou a etapa que ainda não teve nota cadastrada, só me mostram os alunos que não teve nota..

    será que deu pra entender?

    sexta-feira, 16 de setembro de 2011 00:31
  • Bom dia kyrla_nunes,

     

    Não consegui entender...

    Se a disciplina ou etapa ainda não teve nota cadastrada, então acho que todos os alunos não tem nota ainda, ou realmente não entendi a questão.

    E qual opção você utilizou neste teste?

     


    Assinatura: Salas comerciais em Guarulhos
    sexta-feira, 16 de setembro de 2011 14:17
  • sim.. se a etapa e disciplina não tiveram notas cadastradas, todos os alunos não tem nota.. porém todos os alunos precisam aparecer na relação com a nota zerada, pra eu poder lançar a nota..

    pra que vc me entenda, imagine uma turma com N alunos.. estamos na primeira etapa do ano letivo.. você é o professor e vai lançar pela primeira vez a nota de uma prova, pra disciplina que vc dá aulas.. quando vc entra no sistema, vc tem que conseguir visualizar a turma.. da próxima vez, vc continua tendo que visualizar a turma pra lançar a nota da segunda prova..

    e pra isso, vc vai ver um quadro com algumas notas já preenchidas pro alunos que fizeram a prova, e vazia pra quem não fez..

    mas todos os alunos da turma, sempre, tem que aparecer no quadro.. e quando houver nota lançada pra ele naquela disciplina e etapa, a nota vai aparecer lá..

    eu fiz o teste como o sql que vc me mandou.. só defini além da turma, uma disciplina e uma etapa..

    sábado, 17 de setembro de 2011 01:35
  • Blz, entendi o que você quer obter, mas não entendi 100% o que você conseguiu obter com a instrução SQL sugerida.

    Revisando, com uma turma, uma disciplina (ex: 2) e uma etapa (ex: 1) acho que deveria ficar mais ou menos assim:

     

     where 
        (t.at_cdturma = 9) and 
        ( ( (e.at_cdetapa = 1) and (td.at_coddisciplina = 2) ) or
          ( (e.at_cdetapa is null) and (td.at_coddisciplina is null) ) )
    

     

    Espero que seja útil.

     


    Assinatura: Salas comerciais em Guarulhos
    sábado, 17 de setembro de 2011 03:19
  •  

    consegui fazer mais ou menos fazendo a lógica no select.. só que, quando a inforrmação não é verdadeira, ao inves de colocar o valor que eu sugiro, ele deixa em branco.. e com isso quando rodo o meu projeto, ele só me mostra a coluna nome, pois as demais não tem valor..

    SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN CASE WHEN D.AT_CDDISCIP = '9' THEN CASE WHEN N.AT_CDETAPA = '1' THEN N.AT_NOTA ELSE 0 END END END ) AS Trabalhos

    só que, quando eu deixo só assim no select, ele coloca no lugar do campo o valor que eu setei..

    SUM(CASE WHEN AV.AT_NMAVALIAC = 'Trabalhos' THEN N.AT_NOTA ELSE 0 END ) AS Trabalhos

    no meu where, eu só checo a turma para os dois casos..

     

    e por exemplo.. na primeira forma que te mostrei nessa lógica, se existe uma linha com a disciplina e o trabalho válidos, mas a etapa não, ai ele coloca o 0 só pra essa linha..

     

    nossa.. que dificuldade fazer esse negocio funcionar....

    • Editado kngipa sábado, 17 de setembro de 2011 18:46
    sábado, 17 de setembro de 2011 18:44
  • Então experimente desta forma:

    SUM(CASE WHEN (AV.AT_NMAVALIAC = 'Trabalhos') and
                                (D.AT_CDDISCIP = '9') and 
                                (N.AT_CDETAPA = '1') 
                            THEN N.AT_NOTA 
                            ELSE 0 END ) AS Trabalhos

    Espero que ajude.

     


    Assinatura: Salas comerciais em Guarulhos
    • Editado Eder Costa sexta-feira, 23 de setembro de 2011 13:35 ativação do código
    • Sugerido como Resposta Eder Costa sexta-feira, 23 de setembro de 2011 13:35
    domingo, 18 de setembro de 2011 22:26
  • você saberia me dizer o que eu deveria fazer pra esse mesmo método funcionar para um campo do tipo bool?

    exemplo:

    at_frequencia = bool

    ,SUM(case when f.at_data = '15/09/2011 00:00:00' then f.at_freq end) AS "15/09/2011"

    dá este erro:

    function sum(bit) does not exist

    precisaria usar outra função pra poder fazer essas colunas.. pelo que testei, SUM serve só pra campo do tipo inteiro..

    domingo, 18 de setembro de 2011 23:49
  • essa sugestão, não deu certo, pois ele está multiplicando o valor da nota, pelo que coloco no ELSE, se coloco 3, multiplica por 3, se coloco 0, multiplica por 0.. e como todo valor multiplicado por 0 é 0, da impressão de está certo.. mas não está..

    veja o meu sql..

    SELECT a.at_cdaluno, a.at_nome  
    , SUM(CASE WHEN (AV.AT_NMAVALIAC = 'Trabalhos') AND  (N.AT_CDDISCIPLINA = '9') and (N.AT_CDETAPA = '2') THEN N.AT_NOTA ELSE '4' END) AS Trabalhos 
    from tbturma as t   
    join tbinseriraluno as ta on ta.at_cdturma = t.at_cdturma  
    join tbaluno as a on a.at_cdaluno = ta.at_cdaluno  
    left join tbnota as n on n.at_cdaluno = a.at_cdaluno  
    left join tbavaliacao as av on av.at_cdaval = n.at_cdavaliacao  
    left join tbetapa as e on e.at_cdetapa = av.at_cdetapa  
    left join tbdisciplina as d on d.at_cddiscip = n.at_cddisciplina  
    where t.at_cdturma = 1  
    group by a.at_cdaluno, a.at_nome  
    order by a.at_nome 
    


    observer que meu else está com 4..o resultado sai assim..

    CdAlunos       Alunos           Trabalhos
    1                    Aluno 01        16
    2                   Aluno 02         16
    3                  Aluno 03          16
    4                   Aluno 04          16

     

    pelo que pude observar, ele está multiplicando pelo número de linhas obtidas no select.. se o ELSE for 0, no lugar de 16, vem tudo 0..

    há um erro.. mas se eu não usar o else, ou usar com 0, ele não me atrapalha, porque quando a condição é feita, o valor real vem.. mas seria legal se ficasse correto..

     

    segunda-feira, 19 de setembro de 2011 00:17
  • Desculpe mas discordo um pouco quando você diz que está errado com o uso do 0.

    Basicamente se a nota não é do tipo de avaliação, disciplina ou etapa desejados soma-se 0.

    De qualquer forma, segue outra sugestão:

    SELECT 
        a.at_cdaluno, 
        a.at_nome,
        coalesce(tr.at_nota, 0) as Trabalhos 
    from tbturma as t   
    join tbinseriraluno as ta on ta.at_cdturma = t.at_cdturma  
    join tbaluno as a on a.at_cdaluno = ta.at_cdaluno  
    left join
        (select n.at_cdaluno, sum(n.at_nota) as at_nota
         from tbnota as n
         join tbavaliacao as av on av.at_cdaval = n.at_cdavaliacao
         where 
             (AV.AT_NMAVALIAC = 'Trabalhos') AND
             (N.AT_CDDISCIPLINA = '9') and 
             (N.AT_CDETAPA = '2')
         group by
             n.at_cdaluno) as tr on tr.at_cdaluno = a.at_cdaluno
    where t.at_cdturma = 1  
    order by a.at_nome 

    Espero que seja útil.

     


    Assinatura: Salas comerciais em Guarulhos

    • Editado gapimex segunda-feira, 19 de setembro de 2011 05:07
    • Editado Eder Costa sexta-feira, 23 de setembro de 2011 13:36 Ativação do código
    • Sugerido como Resposta Eder Costa sexta-feira, 23 de setembro de 2011 13:36
    • Marcado como Resposta Eder Costa segunda-feira, 26 de setembro de 2011 17:20
    segunda-feira, 19 de setembro de 2011 04:39