[firebase-br] Duvidas com SQL, left join, view, union, e relacionamento de tabelas

Magnun Oliveira magnun_magnun em hotmail.com
Ter Jul 3 10:59:45 -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 Messenger: converse com os seus amigos online. 
http://messenger.msn.com.br





Mais detalhes sobre a lista de discussão lista