Consulta Banco Postgres

Boa Tarde, pessoal eu estou com um problema para fazer uma consulta no banco de dados , eu faço um select em uma tabela onde eu preciso fazer varios joins mas ai quando um desses join não bate um codigo ele não traz NENHUM registro correspondente. por exemplo eu tenho :

SELECT tab1.campo1, tab1.campo2, tab2.campo1, tab2.campo2
FROM propriedades tab1, pessoas tab2
WHERE tab1.id = tab2.id and [color=red]tab1.id = tab2.id; [/color]

[quote=rib]Boa Tarde, pessoal eu estou com um problema para fazer uma consulta no banco de dados , eu faço um select em uma tabela onde eu preciso fazer varios joins mas ai quando um desses join não bate um codigo ele não traz NENHUM registro correspondente. por exemplo eu tenho :

SELECT tab1.campo1, tab1.campo2, tab2.campo1, tab2.campo2
FROM propriedades tab1, pessoas tab2
WHERE tab1.id = tab2.id and [color=red]tab1.id = tab2.id; [/color][/quote]
esse segundo join é igual ao primeiro.

não entendi tua dúvida.

Você compara uma pk = fk

1º Você fez duas vezes a mesma coisa ou estou vendo coisas?
tab1.id é uma pk
tab2.id é uma fk
Acho que você comparou duas pks, verifica se é isso mesmo, você compara as chaves de relacionamento, pk com fk.

WHERE tab1.id = tab2.id and tab1.id = tab2.id; 

Minha duvida éo seguinte , eu tenho varias condições and no where , o problema que se uma condição não for valida não traz registro nenhum , eu tenho 10 condições validas e uma invalida ai não traz nada, tem geito de trazer os resultados corretos mesmo que uma condição seja invalida? Fui claro? Obrigado

Se você tem vários argumentos e se tiver uma que satisfaça uma das condições?

Troca o operador and pelo or
Você pode fazer algo como

WHERE (codincao1 and codicao2 and condicao3) or (condicao4)

Tem que ver exatamento as condições, acima é um exemplo simples.

Tem outra maneira usando + ?

meu Sql, quando um join não bate ele não traz o registro , queria mudar isso :frowning:

[code]SELECT marco.des_marco,
p.numero_propriedade,
p.nome_proprietario,
p.tamanho_alqueire,
v.nome_vinculo ,
atp.atividade_principal ,
ats.atividade_secundaria ,
frp.renda_principal ,
parem.nome_parentesco
FROM tab_marcos marco,
Propriedade p,
Proprietario pe ,
vinculo v ,
Atividade_principal atp ,
Atividade_secundaria ats ,
Fonte_renda_principal frp ,
Parentesco parem ,
Familias fa
WHERE marco.cd_marco = p.tab_marcos_cd_marco
AND p.Tab_marcos_cd_marco = 'M0’
AND p.tamanho_alqueire <= 123
AND p.tamanho_alqueire > 0
AND p.grupo = 'A’
AND p.numero_propriedade = fa.numero_propriedade
AND fa.numero_propriedade = pe.numero_propriedade
AND pe.familias_cd_familias = fa.cd_familias
AND pe.cod_vinculo = v.cd_tipo_vinculo
AND v.cd_tipo_vinculo =1
AND pe.cd_at_principal = atp.cd_tipo_atividade_principal
AND atp.cd_tipo_atividade_principal = 1
AND pe.cd_fonte_renda_principal = frp.cd_tipo_renda_principal
AND frp.cd_tipo_renda_principal = 1
AND pe.cd_at_secundaria = ats.cd_tipo_atividade_secundaria
AND ats.cd_tipo_atividade_secundaria = 2
AND pe.cd_paretensco = parem.cd_tipo_parentesco
AND parem.cd_tipo_parentesco = 1[quote]

Cria subquery na projeção, a junção é para manter a integridade dos dados na consulta.

Ex.:

SELECT
           tab_marco.*,
          (SELECT
                      p.numero_propriedade
           FROM Propriedade p
           WHERE tab_marco.cd_marco = p.tab_marcos_cd_marco) numero_propriedade
FROM tab_marco

Vai aumentar o custo, mas resolve o seu problema, se não tiver dados vem nulo, você pode usar função isnull ou coalesce do BD.
Uma outra coisa é que você não usa os campos da tabela tab_marco na projeção , você poderia tirar na lista da tabela e ficar com Propriedade como principal.

SELECT * FROM tab_marcos marco join Propriedade p on marco.cd_marco = p.tab_marcos_cd_marco join familias fa on p.numero_propriedade = fa.numero_propriedade join Proprietario pe on pe.numero_propriedade = fa.numero_propriedade AND fa.cd_familias = pe.familias_cd_familias left join vinculo v on pe.cod_vinculo = 1 left join Atividade_principal atp on pe.cd_at_principal = 1 left join Atividade_secundaria ats on pe.cd_at_secundaria = 1 left join Fonte_renda_principal frp on pe.cd_fonte_renda_principal = 1 left join Parentesco parem on pe.cd_paretensco = 1 where p.Tab_marcos_cd_marco = 'M0' AND p.tamanho_alqueire <= 200000 AND p.tamanho_alqueire > 0 AND p.grupo = 'A'

Alguem sabe o que está errado nesse left join sql , ele traz muitos registros a mais

Exatamente isso

left join vinculo v on pe.cod_vinculo = 1   
left join Atividade_principal atp on pe.cd_at_principal = 1   
left join Atividade_secundaria ats on pe.cd_at_secundaria = 1  
left join Fonte_renda_principal frp on pe.cd_fonte_renda_principal = 1   
left join Parentesco parem on pe.cd_paretensco = 1   

Quando você faz algo parecido com que você fez perde a integridade, não da pra confiar no resultado, por exemplo, se tiver 30 registros na tabela vinculo com código 1, isso vai multiplicar para cada resultado.

Você usa left quando você quer que venha a tabela da esquerda independente da direita.
você pode fazer isso

SELECT
            *
FROM tabela1
JOIN tabela2 ON tabela1.pk = tabela2.fk
LEFT JOIN tabela3 ON tabela1pk = tabela3.fk

Onde pk é a prymary key e fk é uma foreing key, com isso você matém consistente o resultado.
Observe que se não tiver registro na tabela3 o resultodo da tabela1 virá na consulta.

LEFT JOIN tabela3 isso quer dizer que a tabela 3 vai para esquera e vai consultar independente das outras tabelas da direita?