Array
(
)

Inner join ou Left outer?

Elton Ésqui
   - 02 ago 2010

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!

Tiago Melo
   - 02 ago 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.

0
|
0

Elton Ésqui
   - 02 ago 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

0
|
0

Emerson
   - 03 ago 2010

use left join

0
|
0

Elton Ésqui
   - 03 ago 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

0
|
0

Emerson
   - 05 ago 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

0
|
0

Elton Ésqui
   - 10 ago 2010

Gerou erro!

Não é possível criar expressão de JOIN direito para esta consulta.

0
|
0

Elton Ésqui
   - 10 ago 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!!!

0
|
0

Elton Ésqui
   - 10 ago 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

0
|
0

Emerson
   - 10 ago 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

0
|
0

Elton Ésqui
   - 10 ago 2010

É quase isso!
Esse exclui o que não tem pausa...mas eu preciso exibir pelo menos se iniciou a operação!

0
|
0

Elton Ésqui
   - 10 ago 2010

Perdoe-me Emerson.
Dessa maneira funcionou sim!!! Ótimo!

Muitíssimo obrigado!

Elton

PS: Responda para eu fechar o tópico com feedback.
Valeu

0
|
0

Emerson
   - 10 ago 2010


Citação:
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


eu estava achando estranho não funcionar dessa maneira. o importante é que o problema foi resolvido.

0
|
0