Duvida ao fazer select em tabelas associativas sem repetir dados no Postgres

7 respostas
J

Oi pessoal, estou enfrentando um probleminha ao fazer um select utilizando tabelas associativas no Postgres...
O caso é o seguinte, tenho a tabela associativa reuniao_pessoa e reuniao_profissional e ao fazer o select gostaria que os dados aparecessem apenas uma vez, e mesmo com a utilização do distinct o mesmo continua repetindo, gerando a tabela da seguinte maneira:

id;pessoa;profissional
1;"PESSOA1";"PROFISSIONAL1"
1;"PESSOA2";"PROFISSIONAL2"
1;"PESSOA1";"PROFISSIONAL2"
1;"PESSOA2";"PROFISSIONAL1"

sendo que o resultado que eu quero é apenas:

1;"PESSOA1";"PROFISSIONAL1"
1;"PESSOA2";"PROFISSIONAL2"

ou

1;"PESSOA1";"PROFISSIONAL2"
1;"PESSOA2";"PROFISSIONAL1"

qualquer um dos dois já bastaria pra mim...

Abaixo segue o comando sql que estou utilizando:

Select distinct  profAcompanhante.nome as profissionaisAcompanhantes, j.id, p.nome as pess



FROM reuniao AS j


LEFT JOIN reuniao_pessoa as pessoas
ON pessoas.reuniao_id = j.id
LEFT JOIN pessoa as p
ON p.id = pessoas.pessoa_id
LEFT JOIN reuniao_profissional as profis
ON profis.reuniao_id = j.id
LEFT JOIN profissional as profAcompanhante
ON profAcompanhante.id = profis.profissionalacompanhantes_id 

WHERE j.id = 1

Espero contar com a ajuda de vocês. Qualquer coisa estou a disposição. Obrigado! ;)

7 Respostas

D

já testou group by?

J

já tentei, porém ele só funciona se fizer o Group by com as seguintes informações:

GROUP BY j.id, profAcompanhante.nome, p.nome

E mesmo assim ele continua trazendo a tabela da mesma maneira de antes.(com 4 resultados, ao invés de 2)…

P

Então e porque não

1;“PESSOA1”;"PROFISSIONAL1"
1;“PESSOA2”;“PROFISSIONAL1”

ou

1;“PESSOA1”;"PROFISSIONAL2"
1;“PESSOA2”;“PROFISSIONAL2”

Pelo que percebo, ou estás a tentar obter uma coisa que não faz sentido ou tens o teu modelo de dados errado.

J

É porque o profissional e a pessoa não tem nenhuma relação direta um com o outro, apenas a reunião que faz uma ligação com eles, e isso faz parte de um sql muito maior, mas só essa parte que está dando problema.
Apenas preciso que apareça o nome das pessoas e dos profissionais que estavam presentes, sem repetir.

Abaixo tem o sql completo não sei se ajuda em algo...

SELECT distinct  profAcompanhante.nome as profissionaisAcompanhantes, j.id, pr.nome as programa,
	pj.nome as projeto,
	prof.nome as profissional,
	s.servico as servico,
	j.hora,(to_char(j.data,'DD/MM/YYYY')) as data,
	j.nomeplano,
	ue.unidade as un_execucao,
	up.unidade as un_proponente,
	o.nome as orgao,
	ci.cidade as cid, j.assuntos as assuntos, j.abertura as abertura, j.informes as informes, j.coordenacao as coordenacao,
	j.secretaria as secretaria, j.outrosParticipantes as outros,  p.nome as pess,

	CASE
		WHEN j.localacompanhamento IN(1)
			THEN 'Unidade'
		WHEN j.localacompanhamento IN(2)
			THEN (select local from reuniao j where j.id = 1)
		
	END as localacompanhamento,


	CASE
		WHEN j.localacompanhamento IN(1)
			THEN ' '
		WHEN j.localacompanhamento IN(2)
			THEN (select outroscep from reuniao j where j.id = 1)
	END as cep,


	CASE
		WHEN j.localacompanhamento IN(1)
			THEN (select u.rua from reuniao j, unidade u where j.localunidade = u.id and j.id = 1 )
		WHEN  j.localacompanhamento IN(2)
			THEN (select outrosrua from reuniao j where j.id = 1)
	END as rua ,


	CASE

		WHEN j.localacompanhamento IN(1)
			THEN (' ')
		WHEN  j.localacompanhamento IN(2)
			THEN (select outrosnumero from reuniao j where j.id = 1)
	END as numero ,



	CASE

		WHEN j.localacompanhamento IN(1)
			THEN (select b.bairro from  reuniao j, unidade u, bairro b where
			j.localunidade = u.id and
			bairro_id = b.id and
			j.id = 1)
		WHEN  j.localacompanhamento IN(2)
			THEN (select outrosbairro.bairro from reuniao j where j.id = 1)
	END as bairro ,



		CASE

		WHEN j.localacompanhamento IN(1)
			THEN (select c.cidade from  reuniao j, unidade u, cidade c where
			j.localunidade = u.id and
			cidade_id = c.id and
			j.id = 1)
		WHEN  j.localacompanhamento IN(2)
			THEN (select c.cidade from reuniao j, cidade c where
			j.cidade = c.id and
			j.id = 1)
	END as cidade ,


	CASE

		WHEN j.localacompanhamento IN(1)
			THEN (select u.estado from  reuniao j, unidade u where
			j.localunidade = u.id and
			j.id = 1)
		WHEN  j.localacompanhamento IN(2)
			THEN (select j.estado from reuniao j where
			j.id = 1)
	END as estado ,



	CASE

		WHEN j.localacompanhamento IN(1)
			THEN (' ')
		WHEN  j.localacompanhamento IN(2)
			THEN (select j.referencia from reuniao j where
			j.id = 1)
	END as referencia


	


FROM reuniao AS j

  
LEFT JOIN programa AS pr
ON j.programa_id = pr.id
LEFT JOIN projeto AS pj
ON j.projeto  = pj.id
LEFT JOIN profissional as prof
ON j.profissionalreferencia_id = prof.id
LEFT JOIN servico as s
ON j.servico_id = s.id
LEFT JOIN unidade as up
ON j.unidadeproponente_id = up.id
LEFT JOIN unidade as ue
ON j.unidadeexecucao_id = ue.id
LEFT JOIN ORGAOGESTOR AS O
ON O.ID = 1
LEFT JOIN CIDADE AS CI
ON O.CIDADE_ID = CI.ID
LEFT JOIN unidade as u
ON j.localunidade = u.id
LEFT JOIN bairro as outrosBairro
ON j.bairro = outrosBairro.id
LEFT JOIN reuniao_pessoa as pessoas
ON pessoas.reuniao_id = j.id
LEFT JOIN pessoa as p
ON p.id = pessoas.pessoa_id
LEFT JOIN reuniao_profissional as profis
ON profis.reuniao_id = j.id AND pessoas.pessoa_id = p.id
LEFT JOIN profissional as profAcompanhante
ON profAcompanhante.id = profis.profissionalacompanhantes_id 

WHERE j.id = 1
P

Se não têm relação porque devem aparecer na mesma linha?

Separa a query em 2, uma para pessoas e outra para profissionais e usa o UNION

J

Não precisam estar na mesma linha, basta apenas aparecer no resultado.

Nunca utilizei o UNION vou dar uma pesquisada aqui. :wink:

Se alguém souber alguma outra maneira de resolver o problema, ou precisar que eu esclareça melhor a duvida estou a disposição. :wink:

EDIT: A opção do Union deu utilizando APENAS as pessoas e profissionais, porém o sql completo é bem maior que isso(postei ali anteriormente) e com UNION não deu porque ambas as tabelas tem que ter o mesmo numero de colunas. =\

S

Olá, Gente boa!
Não sei se estou chegando muito tarde, mas vamos lá!

Normalmente utilizamos o LEFT para trazer todo mundo de ambos os lados dos conjuntos envolvidos, logo, se você quiser evitar duplicidade é melhor que aplique os filtros necessários, para que os não nulos não sejam trazidos.

Por exemplo:

Select distinct  profAcompanhante.nome as profissionaisAcompanhantes
               , j.id
               , p.nome as pess   
FROM reuniao AS j   
LEFT JOIN reuniao_pessoa as pessoas   
ON pessoas.reuniao_id = j.id   
LEFT JOIN pessoa as p   
ON p.id = pessoas.pessoa_id   
LEFT JOIN reuniao_profissional as profis   
ON profis.reuniao_id = j.id   
LEFT JOIN profissional as profAcompanhante   
ON profAcompanhante.id = profis.profissionalacompanhantes_id   
  
WHERE j.id = 1
AND pessoas.reuniao_id is not null
AND p.id is not null
AND profis.reuniao_id is not null
AND profAcompanhante.id is not null;

Qualquer dúvida me coloco à disposição!

Att.

Criado 7 de março de 2012
Ultima resposta 19 de mar. de 2012
Respostas 7
Participantes 4