[firebase-br] Duvidas com SQL, left join, view, union, e relacionamento de tabelas
Magnun Oliveira
magnun_magnun em hotmail.com
Qua Jul 4 09:33:39 -03 2007
TABELAS:
TIPO =
ID_TIPO, TIPO
1 --- AAAAAAAAA
2 --- SUB_ITENS
3 --- BBBBBBBBB
4 --- CCCCCCCCC
5 --- EEEEEEEEE
TAB_PAI =
ID_PAI, ID_TIPO, DESCICAO, VALOR
1 ----- 1 ------ PAI 1 --- 100,00
2 ----- 1 ------ PAI 2 --- 150,00
3 ----- 2 ------ PAI 3 --- 500,00
4 ----- 3 ------ PAI 4 --- 250,00
TAB_FILHO =
ID_FILHO, ID_PAI, ID_TIPO, DESCRICAO, VALOR
1 ------- 3 ----- 3 ------ FILHO 1 PAI 3 -- 100,00
2 ------- 3 ----- 4 ------ FILHO 2 PAI 3 -- 140,00
3 ------- 3 ----- 1 ------ FILHO 3 PAI 3 -- 260,00
Tenho essas tres tabelas, a tabela filho eh uma especie de clone da tabela
pai, pois algumas vezes um resgistro dessa tabela pai terá 1 ou mais
registros na tabela filho, porem na maioria das vezes nao terá nenhum.
Ficou definido entao q, internamente no sistema, sempre q um resitro pai
tiver algum item no filho, seu tipo será 2.
Agora preciso exibir uma lista dos tipos, exceto o tipo 2 q eh o indicador
de sub_itens, e a soma dos valores em TAB_PAI E TAB_FILHO.
fiz o seguinte SQL.
SELECT TIPO.TIPO, SUM(TAB_PAI.VALOR) + SUM (TAB_FILHO.VALOR) AS TOTAL
FROM TIPO
LEFT JOIN TAB_PAI ON TIPO.ID_TIPO = TAB_PAI.ID_TIPO
LEFT JOIN TAB_FILHO ON TIPO.ID_TIPO = TAB_FILHO.ID_TIPO
WHERE TIPO.TIPO <> 'SUB ITENS'
GROUP BY TIPO.TIPO
o retornado foi:
TIPO, TOTAL
AAAAA - 770,00
BBBBB - 350,00
CCCCC - NULL
DDDDD - NULL
Vi q ficou erradoi e separei O SUM:
TIPO, TOTAL_PAI, TOTAL_FILHO
AAAAA - 250,00 - 520,00
BBBBB - 250,00 - 100,00
CCCCC - NULL --- 140,00
DDDDD - NULL --- NULL
O total_FILHO do tipo AAAA continuou errado, pois com esse SQL, ele vincula
um registro da tab_filho para cada registro da tab_pai duplicando assim o
260, retirando o sum ele mostrou:
AAAAA - 100 - 260
AAAAA - 140 - 260
Pensei entao em usar uma view pra juntar tab_pai com a tab filhos em uma
unica tabela, excluindo os tens da tab_pai do tipo 'sub itens'
create view VIEW_UNIAO
(ID_TIPO, DESCRICAO, VALOR)
as
select ID_TIPO, DESCRICAO, VALOR from TAB_PAI where ID_TIPO <> 2
union
select ID_TIPO, DESCRICAO, VALOR from TAB_FILHO
A principio funcionou, o retorno foi:
1 - PAI 1 --------- 100
1 - PAI 2 --------- 150
1 - FILHO 3 PAI 3 - 260
3 - FILHO 1 PAI 3 - 100
3 - PAI 4 --------- 250
4 - FILHO 2 PAI 3 - 140
Assim bastaria um SQL assim:
select TIPO.TIPO, sum(VIEW_UNIAO.VALOR) AS TOTAL
from TIPO
left join VIEW_UNIAO on TIPO.ID_TIPO = VIEW_UNIAO.ID_TIPO
GROUP BY TIPO.TIPO
O problema agora foi que, a view nao está trazendo todos os registros.
Quanto maior for o quantidade de registros maior é o erro, causando assim um
erro no valor do sum.
Coloquei 19.852 registros na tab_pai e desses 3 eram do tipo 2 'SUB_ITENS'
Com isso a primeira parte do union retornaria 19.849 registros
Coloquei 6 registros na tab_filho entao a segunda parte retornaria esses 6
Num total de 19855 registros na view_uniao. Porem nao retornou esse valor,
retornou 18789 registros apenas.
Na realidade, as minhas tabelas nao sao essas, foi apenas uma analogia p/
facilitar o entendimento. No meu caso tem mais dois campos nas tab_pai e
tab_filho. DOC e ORIGEM ambos varchar(10) podendo vir a ser nulos.
entao adicionei o campo DOC nessa view e dessa vez retornou 19522 regstros,
depois adicionei o campo ORIGEM e aih sim retornaram os 19855 registros.
Enfim depois dessa dissertação, veem as perguntas:
usar select TAB_ ... union select TAB_... é confiável? PQ no meu caso nao
retornou o recordcount certo?
usa-la no View q ferrou tudo?
será q é preciso fazer isso msm ou naquele sql inicial com left join da pra
resolver?
e por ultimo, essa estrutura q estou usando é a correta? visto q talves
existira algum registro na tab_filho pra um na tabela pai?
Obrigado e descupem o texto gigante, é q tentei ao maximo passar o q
ocorreu.
_________________________________________________________________
MSN Busca: fácil, rápido, direto ao ponto. http://search.msn.com.br
Mais detalhes sobre a lista de discussão lista