Usuário com melhor resposta
Ajuda com query

Pergunta
-
Caros, bom dia.
Estou penando para conseguir o resultado correto de uma query. Seguem detalhes:
Tenho as tabelas COLABORADOR, AFASTAMENTO, PROJETO, DIASUTEIS, VR_COLABORADOR, VALE_REFEICAO, HISTORICO
A tabela COLABORADOR tem 200 registros. Já as outras, depende do que for lançado.
O resultado que preciso na query é:
200 linhas (uma para cada colaborador), e o colaborador que não tiver dado lançado nas outras tabelas aparecer NULL ou algo do tipo, ao invés de não aparecer. Deu pra entender?Segue query até agora, mas só aparece o pessoal que tem algum registro em AFASTAMENTO. Os colaboradores que não tem nada lançado, nem aparece
SELECT c.nome AS Colaborador, p.projeto AS Projeto, d.diasuteis AS DiasUteis, d.mes AS MesDiasUteis, vr.valor AS Valor, SUM(a.dias_refeicao) AS Refeicao, MONTH(a.periodo_de) AS Mes, ((d.diasuteis - SUM(a.dias_refeicao)) * vr.valor) AS ValorMes FROM tb_colaborador c join afastamento a ON a.id_colaborador = c.id_colaborador join historico h ON h.id_colaborador = c.id_colaborador join projetos p ON p.id_projeto = h.id_projeto join diasuteis d ON d.id_projeto = p.id_projeto join vr_colaborador vrc ON vrc.id_colaborador = c.id_colaborador join vale_refeicao vr ON vr.id_vr = vrc.id_vr WHERE MONTH(periodo_de) = 6 and h.termino is null and d.mes = 6 and vrc.atual = 1 GROUP BY c.nome, p.projeto, d.diasuteis, vr.valor, d.mes, MONTH(a.periodo_de)
Leonardo D'Amato Microsoft .Net Developer
Respostas
-
Bom dia,
Leonardo, as colunas da tabela relacionada serão nulas se for utilizado o Left Join e não existir uma linha correspondente, então é necessário prever isso nas condições da clausula Where.
Repare por exemplo que se não existir uma linha na tabela Afastamento para um determinado Colaborador, o valor da coluna a.periodo_de será nulo, então a condição abaixo não será verdadeira:
MONTH(periodo_de) = 6
seria necessário altera-la para algo como segue para que esse colaborador seja retornado:
(MONTH(periodo_de) = 6 or periodo_de is null)
Espero que ajude.
Assinatura: http://www.imoveisemexposicao.com.br
- Marcado como Resposta Leonardo N. D'Amato sexta-feira, 5 de julho de 2013 14:21
Todas as Respostas
-
Leonardo,
Tente desta forma:
SELECT
c.nome AS Colaborador,
p.projeto AS Projeto,
d.diasuteis AS DiasUteis,
d.mes AS MesDiasUteis,
vr.valor AS Valor,
SUM(a.dias_refeicao) AS Refeicao,
MONTH(a.periodo_de) AS Mes,
((d.diasuteis - SUM(a.dias_refeicao)) * vr.valor) AS ValorMes
FROM tb_colaborador c
left join afastamento a ON a.id_colaborador = c.id_colaborador
left join historico h ON h.id_colaborador = c.id_colaborador
join projetos p ON p.id_projeto = h.id_projeto
join diasuteis d ON d.id_projeto = p.id_projeto
left join vr_colaborador vrc ON vrc.id_colaborador = c.id_colaborador
left join vale_refeicao vr ON vr.id_vr = vrc.id_vr
WHERE
MONTH(periodo_de) = 6
and
h.termino is null
and
d.mes = 6
and
vrc.atual = 1
GROUP BY c.nome, p.projeto, d.diasuteis, vr.valor, d.mes, MONTH(a.periodo_de)
Fabrizzio A. Caputo
MCT
Certificações:
Oracle OCA 11g
MCITP SQL Server 2008 Implementation and Maintenance
MCITP SQL Server 2008 Developer
ITIL V3 Foundation
Blog Pessoal: www.fabrizziocaputo.wordpress.com
Email: fabrizzio.antoniaci@gmail.com- Editado Fabrizzio CaputoModerator sexta-feira, 5 de julho de 2013 12:56 Alteração
-
-
-
-
Exatamente Kelvin.
Assim, eu tenho 200 colaboradores, para 13 eu lancei afastamento. A query me retorna apenas estes 13, porém, preciso que retorne os 200, e um nulo nos campos de afastamento para quem não tem nada lançado.
Leonardo D'Amato Microsoft .Net Developer
-
Saquei.
Bom cara, pelo que vi a sua query está certa, porem tem um detalhe que normalmente pega a gente.
Inner Join.
Esses "join" que voce tem no meio da query devem ser no padrão inner join (isso eu estou deduzindo, me corrija se to falando besteira). Quando a gente usa Inner Join, o registro deve estar nas duas tabelas.
FROM tb_colaborador c join afastamento a ON a.id_colaborador = c.id_colaborador join historico h ON h.id_colaborador = c.id_colaborador join projetos p ON p.id_projeto = h.id_projeto join diasuteis d ON d.id_projeto = p.id_projeto join vr_colaborador vrc ON vrc.id_colaborador = c.id_colaborador join vale_refeicao vr ON vr.id_vr = vrc.id_vr
Nesse seu codigo voce está dizendo que quer retornar SOMENTE os registros que possuem todas essas relações. Uma solução pra resolver isso é colocar todos como Left Join, assim ele vai te retornar os 200 registros.
Agora pra sua duvida de retornar uma palavra quando o campo for nulo voce pode usar a função COALESCE.
SELECT CODIGO, COALESCE(NOME_CLIENTE,"Cliente sem nome") AS NOME_CLIENTE FROM CLIENTES
Nesse codigo informo que se a coluna NOME_CLIENTE for nula, irá me retornar "Cliente sem nome" por padrão.
-
-
Então é hora de testar.
Voce já tentou tirar alguns campos do select pra ver se retorna os 200?
por exemplo
SELECT c.nome AS Colaborador FROM tb_colaborador c join afastamento a ON a.id_colaborador = c.id_colaborador join historico h ON h.id_colaborador = c.id_colaborador join projetos p ON p.id_projeto = h.id_projeto join diasuteis d ON d.id_projeto = p.id_projeto join vr_colaborador vrc ON vrc.id_colaborador = c.id_colaborador join vale_refeicao vr ON vr.id_vr = vrc.id_vr WHERE MONTH(periodo_de) = 6 and h.termino is null and d.mes = 6 and vrc.atual = 1 GROUP BY c.nome, p.projeto, d.diasuteis, vr.valor, d.mes, MONTH(a.periodo_de)
Pra ver se é um dos campos que estão influenciando
-
-
-
Continuo restornando 13?
Voce alterou pra ir com left join?
SELECT c.nome AS Colaborador FROM tb_colaborador c left join afastamento a ON a.id_colaborador = c.id_colaborador left join historico h ON h.id_colaborador = c.id_colaborador left join projetos p ON p.id_projeto = h.id_projeto left join diasuteis d ON d.id_projeto = p.id_projeto left join vr_colaborador vrc ON vrc.id_colaborador = c.id_colaborador left join vale_refeicao vr ON vr.id_vr = vrc.id_vr WHERE MONTH(periodo_de) = 6 and h.termino is null and d.mes = 6 and vrc.atual = 1 GROUP BY c.nome, p.projeto, d.diasuteis, vr.valor, d.mes, MONTH(a.periodo_de)
Não dando certo, voce pode analisar o que um desses 13 registros tem que os outros não tem, especificamente.
-
Bom dia,
Leonardo, as colunas da tabela relacionada serão nulas se for utilizado o Left Join e não existir uma linha correspondente, então é necessário prever isso nas condições da clausula Where.
Repare por exemplo que se não existir uma linha na tabela Afastamento para um determinado Colaborador, o valor da coluna a.periodo_de será nulo, então a condição abaixo não será verdadeira:
MONTH(periodo_de) = 6
seria necessário altera-la para algo como segue para que esse colaborador seja retornado:
(MONTH(periodo_de) = 6 or periodo_de is null)
Espero que ajude.
Assinatura: http://www.imoveisemexposicao.com.br
- Marcado como Resposta Leonardo N. D'Amato sexta-feira, 5 de julho de 2013 14:21
-
Já estava com o left join Kelvin.
Pelo retorno, está me dando a entender que o problema é a tabela Afastamento mesmo. Pois inseri um afastamento para um colaborador aqui, e passou de 13 para 14 linhas o retorno.
Leonardo D'Amato Microsoft .Net Developer
-
E ao inserir um afastamento voce também preenche alguma das outras tabelas que voce usou no SELECT? se for isso provavelmente deve ser o seu Where mesmo, como disse o gabimex, é bom atentar para a sua cláusula WHERE agora.
Por exemplo o trecho abaixo
h.termino is null
se voce tiver 1 funcionario que o afastamento já tenha terminado, ele não será retornado devido a esta cláusula.
-