Unir tabelas

SQL

Delphi

Automação Comercial

Banco de Dados

Firebird

12/01/2017

Bom Dia pessoal,

Como faço para gerar um relatório unindo 3 tabelas sendo:

Tabela de Funcionários (Total de registros: 3458 mais ou menos)
Cracha+Nome
1-Ednaldo
2-Antonio
3-Divino
4-Gilmar
5-Manoel
6-Marcos


Tabela 1 (Total de registros: 59000 mais ou menos)
Cracha+Hora,
1-hora: 10
2-Hora: 20
5-hora: 14


Tabela 2 (Total de registros: 50000 mais ou menos)
Cracha+Hora
2-Hora: 21
4-Hora: 12
5-hora: 14


No relatório:
Cracha+Nome+Tabela1+Tabela2
1-Ednaldo-10-0
2-Antonio-20-21
4-Gilmar-0-12
5-Manoel-14-14

Obs:
Nas tabelas 1 e 2 não existem os crachas 3 e 6 portanto não vão sair no relatório.
Nas tabelas 1 e 2, estão registrados os dias do mes, hora entrada, hora saida


Fiz a procedure abaixo, deu certo, só que demora muiiiiito:


create or alter procedure SP_COMPARATIVO_HORAS (
DIA_I date,
DIA_F date)
returns (
CRACHA integer,
DATA date,
NOME varchar(50),
HORAET_01 integer,
HORAST_01 integer,
HORAED_01 integer,
HORASD_01 integer,
HORAET_02 integer,
HORAST_02 integer,
HORAED_02 integer,
HORASD_02 integer,
EVENTO_01 VARCHAR_20,
EVENTO_02 VARCHAR_20)
as
declare variable VDATA date;
declare variable ACHOUT INTEIRO;
declare variable ACHOUB INTEIRO;
declare variable VCRACHA INTEIRO;
declare variable VNOME varchar(50);
begin
-- Tabela de funcionarios
For Select cracha, nome
from funcionarios d
Where demitido = 'N'
Order by cracha
Into :vcracha, :vnome
Do Begin

-- Verifico se existe registro na tabela 1
select count(*) from Tabela1 d
Where d.data between :dia_i and :dia_f and d.cracha = :vcracha
into :achoub;

--Verifico se existe registro na tabela 2
select count(*) from Tabela2 d
Where d.data between :dia_i and :dia_f and d.cracha = :vcracha
into :achout;

--Se Processar somente se exister na tabela 1 e 2
if (achoub+achout > 0 ) then
Begin
cracha = vcracha;
nome = vnome;
vdata = dia_i;
While (vdata <= dia_f) do
Begin
HORAET_01 = 0; HORAST_01 = 0;
HORAED_01 = 0; HORASD_01 = 0;
HORAET_02 = 0; HORAST_02 = 0;
HORAED_02 = 0; HORASD_02 = 0;
evento_01 = Null;
evento_02 = Null;

data = vdata;
-- Se existir na tabela 1
if (achoub > 0) then
Begin
For select d.horae_01, d.horas_01, d.horae_02, d.horas_02
from Tabela1 d
Where d.data = :Vdata and d.cracha = :cracha
into :horaed_01, :horasd_01, :horaed_02, :horasd_02
do begin
if (horaed_01 > 2359) then
Begin
select e.descricao from eventos e
Where e.codigo = :horaed_01
Into :evento_01;
end
if (horaed_02 > 2359) then
Begin
select e.descricao from eventos e
Where e.codigo = :horaed_02
Into :evento_02;
end
end
end

--Se existir na tabela 2
if (achout > 0) then
Begin
Select t.horae_01, t.horas_01, t.horae_02, t.horas_02
from Tabela2 t
Where t.data = :Vdata and t.cracha = :cracha
Into :horaet_01, :horast_01, :horaet_02, :horast_02;
end
vData = vData + 1;
suspend;
end
end
Else
Suspend;
end
end


Desde já agradeço.


Vlw
Dirceu Morais

Dirceu Morais

Curtidas 0

Respostas

Gutierry Pereira

Gutierry Pereira

12/01/2017

Boa tarde,
Por que não faz usando um left join com a tabela 1 e 2.
Se funcionario tiver 1 para 1 ou 0 nas tabelas 1 e 2, pode fazer um left join. Ao final adicionar um where onde o valor resultante da um e 2 tiver alguma coisa.
Caso a tabela 1 e 2 tenha n registros para a funcionario podes fazer um join com um select com sum dos resultados do funcionario, assim tendo o total de horas de cada tabela e ao final adicionando um where para apresentar apenas os que contem horas na tabela 1 e 2, ou que tenham dados na tabela um ou 2.
GOSTEI 0
Dirceu Morais

Dirceu Morais

12/01/2017

Boa tarde,
Por que não faz usando um left join com a tabela 1 e 2.
Se funcionario tiver 1 para 1 ou 0 nas tabelas 1 e 2, pode fazer um left join. Ao final adicionar um where onde o valor resultante da um e 2 tiver alguma coisa.
Caso a tabela 1 e 2 tenha n registros para a funcionario podes fazer um join com um select com sum dos resultados do funcionario, assim tendo o total de horas de cada tabela e ao final adicionando um where para apresentar apenas os que contem horas na tabela 1 e 2, ou que tenham dados na tabela um ou 2.


Não consegui captar sua ideia.

Tentei fazer +- como você disse, mas acho que não funcionou corretamente, pois, demorou igual ou até mais.
Tem como você colocar um exemplo?
GOSTEI 0
Gutierry Pereira

Gutierry Pereira

12/01/2017

Bom dia, a questão de demorar mais não necessariamente quer dizer que não funcionou. Você pode estar com algum gargalo no banco. Se assim funcinou ao menos a manutenção será mais facil que eu uma procedure no banco. Tente verificar se os campos que estão sendo usados nas consultas estão corretamente indexados.
Utilize alguma ferramenta para analisar o desempenho/performace da sua consulta para identificar aonde esta o gargalo.
GOSTEI 0
POSTAR