Select em varias tabelas...

Delphi

13/12/2006

Olá a todos.

Estou com o seguinte problema: ´Tenho tres tabelas para cadastro de clientes, fornecedores, pessoa fisica e pessoa juridica: CLIFOR, PESSOAFISICA e PESSOAJURIDICA. Agora, estou precisando fazer uma uniao dos clientes, idependente de que sejam PESSOA FISICA ou PESSOA JURIDICA. Se eu utilizar um INNER JOIN normalmente, dá certo, no entanto, o campo CPF que é de cliente PESSOAFISICA, ficara em branco quando o cadastro é de PESSOAJURIDICA, e o mesmo acontece com o CNPJ quendo o cliente é PESSOAFISICA. Como montar uma query que faça a uniao dessas informações e exiba tudo em uma unica tupla, sem que fique campos vazios. Fiz a seguinte query:
SELECT CLF_CLIFOR.ID_CLIFOR, CLF_CLIFOR.CODCF, CLF_CLIFOR.TIPO, CLF_CLIFOR.PESSOA, CLF_CLIFOR.NOME,
       CLF_PESSOAFISICA.CPF AS "CNPJ/CPF"
  FROM CLF_CLIFOR
    INNER JOIN CLF_PESSOAFISICA ON CLF_CLIFOR.ID_CLIFOR = CLF_PESSOAFISICA.ID_CLIFOR

UNION

SELECT CLF_CLIFOR.ID_CLIFOR, CLF_CLIFOR.CODCF, CLF_CLIFOR.TIPO, CLF_CLIFOR.PESSOA, CLF_CLIFOR.NOME,
       CLF_PESSOAJURIDICA.CNPJ AS "CNPJ/CPF"
  FROM CLF_CLIFOR
    INNER JOIN CLF_PESSOAJURIDICA ON CLF_CLIFOR.ID_CLIFOR = CLF_PESSOAJURIDICA.ID_CLIFOR
Mas esta dando o seguinte erro:
Dynamic SQL Error
SQL error code = -104
Invalid command
Data type unknown
Statement: SELECT * FROM LISTACLIENTE
UNION
 SELECT * FROM LISTAFORNECEDOR
Também tentei criando VIEW´s e o erro continuou o mesmo.

Alguem pode me ajudar com isso?


Marcelo

Marcelo

Curtidas 0

Respostas

Arc

Arc

13/12/2006

os campos cnpj e cpf são do mesmo tipo ????


GOSTEI 0
Marcelo

Marcelo

13/12/2006

Ambos são CHAR, a diferenca é o tamanho de cada um!


GOSTEI 0
Arc

Arc

13/12/2006

eu to pesquisando essa mensagem de erro, encontrei uma pessoa que falou que pode ser por causa do tamanho do campo, eu não acredito muito nisso não, mas quem sabe né.....

estou tentando simular esse seu select, vamos ver se da o mesmo erro :D


GOSTEI 0
Arc

Arc

13/12/2006

pergunto:
pq das tabelas CLF_PESSOAJURIDICA e CLF_PESSOAFISICA ???


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

13/12/2006

tente assim:
SELECT
  CLF_CLIFOR.ID_CLIFOR, CLF_CLIFOR.CODCF, CLF_CLIFOR.TIPO, CLF_CLIFOR.PESSOA, CLF_CLIFOR.NOME,
  isnull(CLF_PESSOAJURIDICA.CNPJ, CLF_PESSOAFISICA.CPF) AS "CNPJ/CPF"
FROM
  CLF_CLIFOR
LEFT JOIN 
  CLF_PESSOAFISICA ON CLF_PESSOAFISICA.ID_CLIFOR = CLF_CLIFOR.ID_CLIFOR
LEFT JOIN
  CLF_PESSOAJURIDICA ON CLF_PESSOAJURIDICA.ID_CLIFOR = CLF_CLIFOR.ID_CLIFOR

ou simplesmente inverta as instruções. procure primeiro na tabela de pessoas jurídicas e depois na de pessoas físicas, visto que o campo maior pode conter o menor, mas o contrário não é verdadeiro.

como você não informou qual o banco de dados, a instrução foi ilustrada utilizando [i:c6fcdd045f]isnull()[/i:c6fcdd045f], que é uma função do SQL Server. no caso de usar Firebird, troque por [i:c6fcdd045f]coalesce()[/i:c6fcdd045f], ou [i:c6fcdd045f]nvl()[/i:c6fcdd045f] se usar oracle

e faço minha a pergunta anterior: porque CLF_PESSOAJURIDICA e CLF_PESSOAFISICA ?


GOSTEI 0
Arc

Arc

13/12/2006

Caro emerson.en
eu não sei se é isso mesmo, mas pelo que eu entendi desse modelo de dados os campos CLF_PESSOAJURIDICA.CNPJ e CLF_PESSOAFISICA.CPF nunca serão nulas !!!!!


GOSTEI 0
Arc

Arc

13/12/2006

se o campo CLF_CLIFOR.TIPO indicar se é juridica(J) ou fisica (F), poderia ficar assim

SELECT
CLF_CLIFOR.ID_CLIFOR, CLF_CLIFOR.CODCF, CLF_CLIFOR.TIPO, CLF_CLIFOR.PESSOA, CLF_CLIFOR.NOME,
CASE CLF_CLIFOR.TIPO
WHEN ´J´ THEN CLF_PESSOAJURIDICA.CNPJ
ELSE CLF_PESSOAFISICA.CPF
END
AS ´CNPJ/CPF´
FROM
CLF_CLIFOR
LEFT JOIN
CLF_PESSOAFISICA ON CLF_PESSOAFISICA.ID_CLIFOR = CLF_CLIFOR.ID_CLIFOR
LEFT JOIN
CLF_PESSOAJURIDICA ON CLF_PESSOAJURIDICA.ID_CLIFOR = CLF_CLIFOR.ID_CLIFOR


GOSTEI 0
Arc

Arc

13/12/2006

se o campo CLF_CLIFOR.TIPO indicar se é juridica(J) ou fisica (F), poderia ficar assim

SELECT
CLF_CLIFOR.ID_CLIFOR, CLF_CLIFOR.CODCF, CLF_CLIFOR.TIPO, CLF_CLIFOR.PESSOA, CLF_CLIFOR.NOME,
CASE CLF_CLIFOR.TIPO
WHEN ´J´ THEN CLF_PESSOAJURIDICA.CNPJ
ELSE CLF_PESSOAFISICA.CPF
END
AS ´CNPJ/CPF´
FROM
CLF_CLIFOR
LEFT JOIN
CLF_PESSOAFISICA ON CLF_PESSOAFISICA.ID_CLIFOR = CLF_CLIFOR.ID_CLIFOR
LEFT JOIN
CLF_PESSOAJURIDICA ON CLF_PESSOAJURIDICA.ID_CLIFOR = CLF_CLIFOR.ID_CLIFOR


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

13/12/2006

Caro emerson.en eu não sei se é isso mesmo, mas pelo que eu entendi desse modelo de dados os campos CLF_PESSOAJURIDICA.CNPJ e CLF_PESSOAFISICA.CPF nunca serão nulas !!!!!

claro que poderá ser nulo.
um cliente não pode ser ao mesmo tempo pessoa física e pessoa jurídica. se for pessoa física, o valor de pessoa jurídica será nulo, e vice-versa.


GOSTEI 0
Arc

Arc

13/12/2006

ok, até ai tudo bem , mas se realmente o campo tipo for para diferenciar fisica de juridica, então qdo vc cadastra uma pessoa fisica acredito que somente a tabela CLF_PESSOAFISICA seja atualizada com o codigo do cliente/fornecedor e o CPF assim como para pessoa Juridica onde somente a tabela CLF_PESSOAJURIDICA será atualizada com o codigo e o CNPJ, nunca as duas tabelas ao mesmo tempo ao incluir um novo cliente/fornecedor


GOSTEI 0
Emerson Nascimento

Emerson Nascimento

13/12/2006

exato!
por isso optei pelo [i:69e764bf88]isnull()[/i:69e764bf88] ao invés do [i:69e764bf88]case[/i:69e764bf88].


GOSTEI 0
Arc

Arc

13/12/2006

a tah emerson.en, agora que eu entendi , heheheh
mas e aí marcelo, conseguiu resolver o seu problema???


GOSTEI 0
Marcelo

Marcelo

13/12/2006

Caro amigos... A conversa de vocês estava tão empolgante que nem quis atrapalhar. hehe... Brincadeira!

Olha, o lance é o seguinte: eu modelei o BD totalmente normalizado, por isso criei varias entidades contendo informações pertinentes a cada cadastro. A tabela CLIFOR é para cadastro de CLIENTE e FORNECEDOR independente de ser PESSOA JURIDICA ou PESSOA FISICA. Criei também outras entidades como PESSOAJURIDICA, PESSOAFISICA, CLIENTE, etc. Tendo sempre aquele critério de que dados de cliente são dados de clientes, dados de pessoa física são dados de pessoa física, dados de pessoa jurídica são dados de pessoa jurídica e assim por diante. As informações que todos têm em comum, ficam armazenadas na entidade CLIFOR. Respondi a dúvida quanto a isso?

Agora a respeito do UNION, optei por modificar o tipo da estrutura do banco, deixando tanto CPF quanto CNPJ como CHAR(14). O IB/FB funciona da seguinte maneira: quando você cria algum campo em uma determinada tabela, o IB/FB cria uma DOMAIN interna, representando o tipo juntamente com o tamanho do campo, essa DOMAIN será utilizada internamente sempre que você criar outro campo com o mesmo tipo e tamanho. O UNION apenas funciona quando os DOMAINS das tabelas de união são idênticos, caso contrario ocorre um erro de incompatibilidade de tipo. Valeu a informação?

Gente, muito obrigado pela força e achei interessante a curiosidade de vocês.

Um abraço a todos!!!


GOSTEI 0
POSTAR