Usuário com melhor resposta
Consulta duplicada no banco de dados

Pergunta
-
Olá pessoal!
Preciso de uma ajuda em um SELECT no bando de dados (SQL SERVER).
Segue abaixo 4 tabelas do banco de dados de uma imobiliária que aluga kitnets (moradias).
CREATE TABLE tblImovel (
imov_id INT IDENTITY(1,1),
tpim_id INT FOREIGN KEY REFERENCES tblTipoImovel(tpim_id),
dest_id INT FOREIGN KEY REFERENCES tblDestinacaoImovel(dest_id),
prop_id INT FOREIGN KEY REFERENCES tblProprietario(prop_id),
imov_codigo VARCHAR(30),
imov_endereco VARCHAR(50),
imov_cep VARCHAR(10),
imov_numero VARCHAR(10),
imov_bairro VARCHAR(30),
imov_cidade VARCHAR(30),
imov_estado CHAR(2),
imov_valor MONEY,
imov_iptu MONEY,
imov_pavimentosTotal INT,
imov_dormitorios INT,
imov_dormitoriosComp INT,
imov_banheiros INT,
imov_banheirosComp INT,
imov_suites INT,
imov_kitnets INT,
imov_cozinhas INT,
imov_cozinhasComp INT,
imov_areaServ INT,
imov_areaServComp INT,
imov_quintal INT,
imov_varanda INT,
imov_salao INT,
imov_garagem INT,
imov_dimensTerreno REAL,
imov_dimensAreaConst REAL,
imov_dimensFachada REAL,
imov_norteGeog VARCHAR(100),
imov_observacao VARCHAR(1000),
imov_viasAcesso VARCHAR(1000),
imov_situacao VARCHAR(10),
CONSTRAINT tblImovel_PK PRIMARY KEY(imov_id)
)
GO
CREATE TABLE tblMoradia(
morad_id INT IDENTITY(1,1),
imov_id INT FOREIGN KEY REFERENCES tblImovel(imov_id),
morad_numero VARCHAR(10),
morad_valor MONEY,
morad_dimensaoTotal REAL,
morad_suite INT,
morad_suitePia INT,
morad_banheiro INT,
morad_banheiroComp INT,
morad_cozinha INT,
morad_cozinhaComp INT,
morad_quarto INT,
morad_quartoComp INT,
morad_areaServ INT,
morad_areaServComp INT,
morad_descricao VARCHAR(1000),
morad_situacao VARCHAR(10),
morad_pavimento INT,
CONSTRAINT tblMoradia_PK PRIMARY KEY(morad_id)
)
GO
CREATE TABLE tblMorador(
mora_id INT IDENTITY(1,1),
mora_nome VARCHAR(50),
mora_cpf VARCHAR(12),
mora_rg VARCHAR(20),
mora_profissao VARCHAR(30),
mora_dataNasc DATE ,
mora_telefone VARCHAR(20),
mora_celular VARCHAR(20),
mora_email VARCHAR(50),
mora_observacao VARCHAR(1000),
mora_situacao VARCHAR(10),
CONSTRAINT tblMorador_PK PRIMARY KEY(mora_id)
)
GO
CREATE TABLE tblContrato(
cont_id INT IDENTITY(1,1),
fiad_id INT FOREIGN KEY REFERENCES tblFiador(fiad_id),
prop_id INT FOREIGN KEY REFERENCES tblProprietario(prop_id),
imov_id INT FOREIGN KEY REFERENCES tblImovel(imov_id),
mora_id INT FOREIGN KEY REFERENCES tblMorador(mora_id),
morad_id INT FOREIGN KEY REFERENCES tblMoradia(morad_id),
cont_valor MONEY,
cont_diaVenc INT,
cont_deposito INT,
cont_dataInicio DATE,
cont_dataFim DATE,
cont_habitantes INT,
cont_observacao VARCHAR(512),
cont_situacao VARCHAR(10),
CONSTRAINT tblContrato_PK PRIMARY KEY(cont_id)
)
GO
Inseri um contrato para um determinado morador, em um determinado imóvel e uma moradia atualizando assim o campo situação na tabela tblMoradia para ''OCUPADO'' e o campo situação da tabela tblContrato para ''VIGENTE''. Logo depois esse morador desistiu do contrato e saiu da casa. Dessa forma, eu cancelei o contrato no sistema atualizando a situação da moradia para ''DESOCUPADO'' e a situação do contrato para ''CANCELADO''. Tempos depois um novo morador decide morar nessa mesma moradia e um novo contrato é feito atualizando novamente a situação da tblMoradia para ''OCUPADO''. Por fim, esse novo morador também decide sair da casa cancelando novamente o contrato e atualizando a situação da tblMoradia para ''DESOCUPADO'' e a tblContrato para ''CANCELADO''.
Portanto, gerei dois registro para uma mesma moradia, em dois contratos diferentes.
Gostaria de realizar uma consulta no banco que retornasse somente as moradias (kitnets) disponíveis independente do histórico anterior, ou seja, não quero que ele traga valores repetidos. Entretanto quando realizo a seguinte consulta no banco:
SELECT i.imov_codigo, mo.mora_nome, m.morad_numero, m.morad_pavimento, m.morad_dimensaoTotal, c.cont_valor, i.imov_observacao, i.imov_viasAcesso,
m.morad_suite, m.morad_suitePia, m.morad_banheiro, m.morad_banheiroComp, m.morad_cozinha, m.morad_cozinhaComp, m.morad_quarto,
m.morad_quartoComp, m.morad_areaServ, m.morad_areaServComp, m.morad_descricao, m.morad_situacao, c.cont_situacao
FROM tblMoradia m FULL OUTER JOIN tblImovel i
ON m.imov_id=i.imov_id FULL OUTER JOIN tblContrato c
ON c.morad_id=m.morad_id FULL OUTER JOIN tblMorador mo
ON mo.mora_id=c.mora_id
WHERE i.imov_codigo=@cod AND m.morad_situacao=@situacao
em que @cod equivale ao código do imóvel alugado e @situacao=''DESOCUPADO'' ele retorna todas moradias desocupadas e para a moradia que foi alugada mais de uma vez, ele traz todos os registos gerados (no exemplo citado, são ao todo 2 registros). Entretanto eu preciso consultar somente as moradias desocupadas independente do número de registros gerados. Não quero que os registros se repitam.
Espero que tenha sido claro. Desde já agradeço.
Respostas
-
Você quer trazer a última posição por moradia. Então eu sugiro que você ...
1-Acrescente na consulta atual um ROW_NUMBER() OVER (PARTITION BY moradia ORDER BY alguma_data ou algum_id desc) AS reg;
2-Utilize essa consulta como subquery, e então utilize a coluna criada em uma clausula WHERE reg = 1
Dessa forma sempre será mostrado o ultimo registro por moradia. Pense nisso ...
Wyllian de Lima - Se a resposta ajudou vote como útil !
- Sugerido como Resposta Junior Galvão - MVPMVP sexta-feira, 9 de fevereiro de 2018 12:37
- Marcado como Resposta Filipe B CastroModerator sexta-feira, 9 de fevereiro de 2018 17:17
Todas as Respostas
-
-
Walsan,
Troca o "OUTER JOIN" por "inner join".
O "OUTER JOIN" retorna todos os registros de ambas as tabelas.
Carlos_rodrigues,
Obrigado por responder mas nesse caso preciso do OUTER JOIN pois existe a possibilidade de ter moradias novas que nunca foram alugadas e que por isso não tem nenhum histórico de contrato ou morador. Quando coloco o INNER essas moradias não aparecem. :(
-
-
Talvez não seja a melhor opção, mas se vc acrescentar o distinct talvez resolva seu problema
Mesmo usando o DISTINCT e o INNER JOIN a consulta ainda puxa todos os registro gerados, inclusive os repetidos. Você consegue ver outra solução?
Preciso muito terminar essa consulta, que teoricamente parecia simples mas não estou conseguindo mostrar na tela somente as moradias desocupadas para um determinado imóvel.
-
Você quer trazer a última posição por moradia. Então eu sugiro que você ...
1-Acrescente na consulta atual um ROW_NUMBER() OVER (PARTITION BY moradia ORDER BY alguma_data ou algum_id desc) AS reg;
2-Utilize essa consulta como subquery, e então utilize a coluna criada em uma clausula WHERE reg = 1
Dessa forma sempre será mostrado o ultimo registro por moradia. Pense nisso ...
Wyllian de Lima - Se a resposta ajudou vote como útil !
- Sugerido como Resposta Junior Galvão - MVPMVP sexta-feira, 9 de fevereiro de 2018 12:37
- Marcado como Resposta Filipe B CastroModerator sexta-feira, 9 de fevereiro de 2018 17:17
-
Você quer trazer a última posição por moradia. Então eu sugiro que você ...
1-Acrescente na consulta atual um ROW_NUMBER() OVER (PARTITION BY moradia ORDER BY alguma_data ou algum_id desc) AS reg;
2-Utilize essa consulta como subquery, e então utilize a coluna criada em uma clausula WHERE reg = 1
Dessa forma sempre será mostrado o ultimo registro por moradia. Pense nisso ...
Wyllian de Lima - Se a resposta ajudou vote como útil !
Obrigado Wyllian. Testei aqui e deu certo, muito obrigado. :)