Inner join ou Left outer?
Caros
Estou realizando uma consulta onde o resultado será o seguinte:
Resumidamente!
Usuario, Login, Logout, ini_pausa, fim_pausa
Essas informações estão em tabelas diferentes.
A consulta "funciona" com inner join, mas se o usuário não efetuou pausa (ini_pausa e fim_pausa), ele não é exibido no resultado.
Preciso que esse usuário seja exibido mesmo sem essa informação.
Help! I need somebody, help!
Estou realizando uma consulta onde o resultado será o seguinte:
Resumidamente!
Usuario, Login, Logout, ini_pausa, fim_pausa
Essas informações estão em tabelas diferentes.
A consulta "funciona" com inner join, mas se o usuário não efetuou pausa (ini_pausa e fim_pausa), ele não é exibido no resultado.
Preciso que esse usuário seja exibido mesmo sem essa informação.
Help! I need somebody, help!
Elton ésqui
Curtidas 0
Respostas
Tiago Melo
02/08/2010
Elton, o inner join é uma clausula que exibe os registros somente quando os registros de usando na clausula "on" existe tanto na tabela pai quanto na tabela filha, sendo assim para que os registros sejam exibidos os campos utilizados em "on" deveram conter exatamente os mesmos valores nas duas tabelas...já o left join dá pra preferencia para a tabela da esquerda, ou seja mesmo que não haja registro na tabela da direita pelo menos os registros da tabela da esquerda serão apresentados...ex:
select p.NomePai, f.NomeFilho from Tabela_Pai p
inner join Tabela_Filho f
on p.IdPai = f.IdFilho
**nesse exemplo caso não haja um filho correspondente a um pai cadastrado na tabela filho o result set retornará vazio.
select p.NomePai, f.NomeFilho from Tabela_Pai p
left outer join Tabela_Filho f
on p.IdPai = f.IdFilho
**nesse exemplo mesmo que não haja um filho correspondente a um pai cadastrado na tabela filho, pelo menos o pai que está cadastrado na tabela pai será apresentado isso porque o "join" está dando preferencia para a tabela da esquerda, que é a tabela Tabela_Pai, o mesmo conceito é válido para RIGTH JOIN.
GOSTEI 0
Elton ésqui
02/08/2010
Bom, tentei usar o LEFT e RIGHT onde entendi que deveria ser, mesmo assim não obtive o resultado desejado.
Segue abaixo como as tabelas estão ligadas.
O que preciso: Exibir o resultado mesmo quando só tenha registro na tabela LIG_CAB (campo: INI_OPER).
Ou seja, independente de exisitir ou não a pausa, deverá mostrar o operador que iniciou a operação (INI_OPER)
Obrigado!
Segue o select utilizado:
SELECT
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
VROPERAD V
INNER JOIN OPEPAUSA O ON (V.CODIGO = O.OPERADOR)
INNER JOIN MPAUSA M ON (O.MOTIVO = M.CODIGO)
INNER JOIN LIG_CAB L ON (O.OPERADOR = L.OPERADOR)
WHERE
O.DATA BETWEEN '07/28/2010' AND '08/02/2010' AND
L.DATA BETWEEN '07/28/2010' AND '08/02/2010'
ORDER BY
O.DATA
Segue abaixo como as tabelas estão ligadas.
O que preciso: Exibir o resultado mesmo quando só tenha registro na tabela LIG_CAB (campo: INI_OPER).
Ou seja, independente de exisitir ou não a pausa, deverá mostrar o operador que iniciou a operação (INI_OPER)
Obrigado!
Segue o select utilizado:
SELECT
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
VROPERAD V
INNER JOIN OPEPAUSA O ON (V.CODIGO = O.OPERADOR)
INNER JOIN MPAUSA M ON (O.MOTIVO = M.CODIGO)
INNER JOIN LIG_CAB L ON (O.OPERADOR = L.OPERADOR)
WHERE
O.DATA BETWEEN '07/28/2010' AND '08/02/2010' AND
L.DATA BETWEEN '07/28/2010' AND '08/02/2010'
ORDER BY
O.DATA
GOSTEI 0
Emerson Nascimento
02/08/2010
use left join
GOSTEI 0
Elton ésqui
02/08/2010
Teve um comportamento um tanto estranho.
Se, por exemplo, o cara iniciou a operação ontem, mas não efetuou pausas e iniciou a operação hoje e efetuou pausas, no resultado exibe as pausas de hoje na data de ontem. Estranho!!!
Código Nome Ini. operador Fim operador Iníc.Pausa Fim pausa MOTIV_PAUSAS DATA_PAUSAS DATA_INI_OPER 3.00 Peter Pan 30/07/2010 10:32 30/07/2010 17:36 30/07/2010 10:32 30/07/2010 10:32 BANHEIRO 30/07/2010 00:00 30/07/2010 00:00 3.00 Peter Pan 30/07/2010 10:32 30/07/2010 17:36 30/07/2010 10:32 30/07/2010 10:32 ALMOÇO 30/07/2010 00:00 30/07/2010 00:00 3.00 Peter Pan 03/08/2010 09:27 30/07/2010 17:27 30/07/2010 10:32 30/07/2010 10:32 BANHEIRO 30/07/2010 00:00 03/08/2010 00:00 3.00 Peter Pan 03/08/2010 09:27 30/07/2010 17:27 30/07/2010 10:32 30/07/2010 10:32 ALMOÇO 30/07/2010 00:00 03/08/2010 00:00
Se, por exemplo, o cara iniciou a operação ontem, mas não efetuou pausas e iniciou a operação hoje e efetuou pausas, no resultado exibe as pausas de hoje na data de ontem. Estranho!!!
Código Nome Ini. operador Fim operador Iníc.Pausa Fim pausa MOTIV_PAUSAS DATA_PAUSAS DATA_INI_OPER 3.00 Peter Pan 30/07/2010 10:32 30/07/2010 17:36 30/07/2010 10:32 30/07/2010 10:32 BANHEIRO 30/07/2010 00:00 30/07/2010 00:00 3.00 Peter Pan 30/07/2010 10:32 30/07/2010 17:36 30/07/2010 10:32 30/07/2010 10:32 ALMOÇO 30/07/2010 00:00 30/07/2010 00:00 3.00 Peter Pan 03/08/2010 09:27 30/07/2010 17:27 30/07/2010 10:32 30/07/2010 10:32 BANHEIRO 30/07/2010 00:00 03/08/2010 00:00 3.00 Peter Pan 03/08/2010 09:27 30/07/2010 17:27 30/07/2010 10:32 30/07/2010 10:32 ALMOÇO 30/07/2010 00:00 03/08/2010 00:00
GOSTEI 0
Emerson Nascimento
02/08/2010
as tabelas mais devem ser relacionadas da forma correta:
SELECT
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
VROPERAD V
INNER JOIN LIG_CAB L ON (L.OPERADOR = O.OPERADOR)
LEFT JOIN OPEPAUSA O ON (O.OPERADOR = V.CODIGO and O.DATA = L.DATA)
LEFT JOIN MPAUSA M ON (M.CODIGO = O.MOTIVO)
WHERE
L.DATA BETWEEN '07/28/2010' AND '08/02/2010'
ORDER BY
L.DATA
SELECT
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
VROPERAD V
INNER JOIN LIG_CAB L ON (L.OPERADOR = O.OPERADOR)
LEFT JOIN OPEPAUSA O ON (O.OPERADOR = V.CODIGO and O.DATA = L.DATA)
LEFT JOIN MPAUSA M ON (M.CODIGO = O.MOTIVO)
WHERE
L.DATA BETWEEN '07/28/2010' AND '08/02/2010'
ORDER BY
L.DATA
GOSTEI 0
Elton ésqui
02/08/2010
Gerou erro!
Não é possível criar expressão de JOIN direito para esta consulta.
Não é possível criar expressão de JOIN direito para esta consulta.
GOSTEI 0
Elton ésqui
02/08/2010
Parece que incluindo tudo vai!
SELECT
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
OPEPAUSA O
FULL OUTER JOIN LIG_CAB L ON (L.OPERADOR = O.OPERADOR)
AND (O.DATA = L.DATA)
LEFT OUTER JOIN VROPERAD V ON (O.OPERADOR = V.CODIGO)
LEFT OUTER JOIN MPAUSA M ON (M.CODIGO = O.MOTIVO)
WHERE
L.DATA BETWEEN '07/28/2010' AND '08/02/2010'
ORDER BY
L.DATA
Estou testando ainda!!!
SELECT
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
OPEPAUSA O
FULL OUTER JOIN LIG_CAB L ON (L.OPERADOR = O.OPERADOR)
AND (O.DATA = L.DATA)
LEFT OUTER JOIN VROPERAD V ON (O.OPERADOR = V.CODIGO)
LEFT OUTER JOIN MPAUSA M ON (M.CODIGO = O.MOTIVO)
WHERE
L.DATA BETWEEN '07/28/2010' AND '08/02/2010'
ORDER BY
L.DATA
Estou testando ainda!!!
GOSTEI 0
Elton ésqui
02/08/2010
Da maneira anterior, assim como a que está logo abaixo, estão mostrando o resultado como deveria, se não fosse um detalhe:
Quando o operador não tem pausas, no resultado não exibe o código e nome dele.
SELECT
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
VROPERAD V
LEFT OUTER JOIN OPEPAUSA O ON (O.OPERADOR = V.CODIGO)
FULL OUTER JOIN LIG_CAB L ON (L.DATA = O.DATA)
AND (L.OPERADOR = V.CODIGO)
LEFT OUTER JOIN MPAUSA M ON (M.CODIGO = O.MOTIVO)
WHERE
L.DATA BETWEEN '08/06/2010' AND '08/10/2010'
ORDER BY
L.DATA,
V.NOME
Quando o operador não tem pausas, no resultado não exibe o código e nome dele.
SELECT
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
VROPERAD V
LEFT OUTER JOIN OPEPAUSA O ON (O.OPERADOR = V.CODIGO)
FULL OUTER JOIN LIG_CAB L ON (L.DATA = O.DATA)
AND (L.OPERADOR = V.CODIGO)
LEFT OUTER JOIN MPAUSA M ON (M.CODIGO = O.MOTIVO)
WHERE
L.DATA BETWEEN '08/06/2010' AND '08/10/2010'
ORDER BY
L.DATA,
V.NOME
GOSTEI 0
Emerson Nascimento
02/08/2010
SELECT
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
LIG_CAB L
INNER JOIN
VROPERAD V ON (V.CODIGO = L.OPERADOR)
LEFT JOIN
OPEPAUSA O ON (O.OPERADOR = L.OPERADOR and O.DATA = L.DATA)
LEFT JOIN
MPAUSA M ON (M.CODIGO = O.MOTIVO)
WHERE
L.DATA BETWEEN '07/28/2010' AND '08/02/2010'
ORDER BY
L.DATA
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
LIG_CAB L
INNER JOIN
VROPERAD V ON (V.CODIGO = L.OPERADOR)
LEFT JOIN
OPEPAUSA O ON (O.OPERADOR = L.OPERADOR and O.DATA = L.DATA)
LEFT JOIN
MPAUSA M ON (M.CODIGO = O.MOTIVO)
WHERE
L.DATA BETWEEN '07/28/2010' AND '08/02/2010'
ORDER BY
L.DATA
GOSTEI 0
Elton ésqui
02/08/2010
É quase isso!
Esse exclui o que não tem pausa...mas eu preciso exibir pelo menos se iniciou a operação!
Esse exclui o que não tem pausa...mas eu preciso exibir pelo menos se iniciou a operação!
GOSTEI 0
Elton ésqui
02/08/2010
Perdoe-me Emerson.
Dessa maneira funcionou sim!!! Ótimo!
Muitíssimo obrigado!
Elton
PS: Responda para eu fechar o tópico com feedback.
Valeu
Dessa maneira funcionou sim!!! Ótimo!
Muitíssimo obrigado!
Elton
PS: Responda para eu fechar o tópico com feedback.
Valeu
GOSTEI 0
Emerson Nascimento
02/08/2010
SELECT
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
LIG_CAB L
INNER JOIN
VROPERAD V ON (V.CODIGO = L.OPERADOR)
LEFT JOIN
OPEPAUSA O ON (O.OPERADOR = L.OPERADOR and O.DATA = L.DATA)
LEFT JOIN
MPAUSA M ON (M.CODIGO = O.MOTIVO)
WHERE
L.DATA BETWEEN '07/28/2010' AND '08/02/2010'
ORDER BY
L.DATA
V.CODIGO,
V.NOME,
L.INI_OPER,
L.FIM_OPER,
O.INI_PAUSA,
O.FIM_PAUSA,
M.DESCRICAO AS MOTIV_PAUSAS,
O.DATA AS DATA_PAUSAS,
L.DATA AS DATA_INI_OPER
FROM
LIG_CAB L
INNER JOIN
VROPERAD V ON (V.CODIGO = L.OPERADOR)
LEFT JOIN
OPEPAUSA O ON (O.OPERADOR = L.OPERADOR and O.DATA = L.DATA)
LEFT JOIN
MPAUSA M ON (M.CODIGO = O.MOTIVO)
WHERE
L.DATA BETWEEN '07/28/2010' AND '08/02/2010'
ORDER BY
L.DATA
eu estava achando estranho não funcionar dessa maneira. o importante é que o problema foi resolvido.
GOSTEI 0