On 06/12/2012 07:41, Thiago wrote: > On 05/12/2012 17:16, Matheus de Oliveira wrote: >> >> >> 2012/12/5 Thiago <zan...@farmaponte.com.br >> <mailto:zan...@farmaponte.com.br>> >> >> Boa tarde. >> >> Tenho as seguintes tabelas: >> >> tb_mensagem >> id >> id_mensagem_pai >> dth_insert >> >> tb_mensagem_leitura >> id_mensagem >> dth_insert >> >> A tabela de mensagens, sempre que existe uma mensagem com >> id_mensagem_pai, significa que é uma resposta, as mensagens originais >> (primeiras) contém 0 (zero) no campo id_mensagem_pai. >> >> Na tabela tb_mensagem_leitura eu tenho um histórico de todas as vezes >> que o usuário leu a mensagem, sendo gravado no campo id_mensagem dessa >> tabela sempre o id da mensagem original. >> >> Preciso identificar quantas mensagens não lidas existe na para o >> usuário, sendo que uma mensagem não lida é: >> 1) sem registro na tabela tb_mensagem_leitura; >> 2) o registro da tabela tb_mensagem_leitura é com data menor que a >> última resposta da mensagem original. >> >> Alguém poderia me ajudar com este select? Ou até mesmo com a forma em >> que estruturei as tabelas, pois para chegar neste resultado está um >> pouco complicado. >> >> >> Cara, se eu não boiei na maionese, a consulta abaixo resolve o seu >> problema (não testado): >> >> WITH RECURSIVE mensagens AS ( >> SELECT id AS id_original, id, dth_insert >> FROM tb_mensagem >> WHERE id_mensagem_pai = 0 >> UNION ALL >> SELECT pai.id_original, filha.id <http://filha.id>, filha.dth_insert >> FROM tb_mensagem AS filha >> INNER JOIN mensagens AS pai ON pai.id <http://pai.id> = >> filha.id_mensagem_pai >> ), ultimas AS ( >> SELECT m.id_original, MAX(m.dth_insert) AS dth_insert >> FROM mensagens AS m >> GROUP BY m.id_original >> ) >> SELECT COUNT(*) >> FROM ultimas AS u >> LEFT JOIN tb_mensagem_leitura AS l >> ON l.id_mensagem = u.id_original >> WHERE l.id_mensagem IS NULL OR l.dth_insert < u.dth_insert; >> >> >> Não me parece muito performático, uma forma de melhorar seria SEMPRE >> guardar o id da mensagem original em tb_mensagem (não só a da pai, mas a >> da primeira na hierarquia), o que evitaria toda essa sobrecarga da query >> recursiva e da outra sub-query, que na prática só estão pegando a data >> da última mensagem. >> >> Atenciosamente, > > Mateus, muito obrigado pela resposta. > > Acho que não expliquei direito. Na tabela tb_mensagem, o campo > id_mensagem_pai é sempre o id da mensagem original. Todas as respostas > estão amarradas a uma única mensagem e não em um formato de árvore. > > Dessa forma você acha que existe uma solução melhor com uma melhor > performance? Essa será uma leitura muitas vezes executada, pois cada > página do portal que o usuário acessa essa consulta é refeita para > atualizar as mensagens não lidas. > > > _______________________________________________ > pgbr-geral mailing list > pgbr-geral@listas.postgresql.org.br > https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral >
Na verdade eu tenho um outro problema, que deixou as coisas um pouco mais difíceis. Na tabela de mensagem, existem os campos id_usuario_des (destinatário) e id_usuario_rem (remetente). Uma mensagem deve aparecer na caixa de entrada do usuário quando a mensagem original é id_usuario_des on existe pelo menos uma resposta da mensagem original como id_usuario_des igual ao usuário logado. Eu consegui chegar ao resultado desejado da seguinte forma: select count(*) from ( select tm.id_mensagem, max(tm.dth_insert) from ( select case when cr.id_mensagem_pai = 0 then cr.id else cr.id_mensagem_pai end as id_mensagem, cr.dth_insert from portal.tb_correio cr where cr.id_usuario_des = 2 ) as tm where ( select hl.id from portal.tb_correio_historico_leitura hl where hl.id_mensagem = tm.id_mensagem and hl.dth_insert > tm.dth_insert and hl.dth_nao_lido is null and hl.id_usuario = 2 limit 1 ) is null group by tm.id_mensagem ) as tp Porém eu fico com medo quanto a questão de performance. No momento estou com poucas mensagens na base de dados, por isso a query está sendo executada rapidamente, mas daqui há alguns meses ela vai começar a ficar lenta. Alguma sugestão? Obrigado! _______________________________________________ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral