Ir ao conteúdo
  • Cadastre-se

Ajuda em uma select


Posts recomendados

Olá pessoal,

 

tenho uma tabela chamada veículo, onde terá registros de veículos dos tipos caminhão-cavalo ou carreta. Então o campo "tipo" será 1 para cavalo e 2 para carreta.

 

Quando o registro for uma carreta, poderá haver um cavalo vinculado.

 

Há também o campo "desengatado", que será usado caso a carreta possua um vínculo com um cavalo mas não está engatado (objeto físico) no momento.

 

Abaixo a tabela com alguns registros:

 



CREATE TABLE veiculo (
codigo integer,
tipo character(1),
descricao character varying(50),
codigo_vinculo integer,
desengatado boolean,
constraint pk_veiculo PRIMARY KEY (codigo),
constraint fk_veiculo_vinculo FOREIGN KEY (codigo_vinculo) REFERENCES veiculo (codigo)
);

INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (1, '1', 'CAVALO 1', NULL, NULL);
INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (2, '1', 'CAVALO 2', NULL, NULL);
INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (3, '1', 'CAVALO 3', NULL, NULL);

INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (4, '2', 'CARRETA 1', NULL, false);
INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (5, '2', 'CARRETA 2', 1, true);
INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (6, '2', 'CARRETA 3', 2, false);
INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (7, '2', 'CARRETA 4', 1, false);


Agora veja bem, preciso fazer uma consulta que traga todos os veículos do tipo cavalo (2) que não estão vinculados com nenhum veículo do tipo carreta (1), ou que possa ter o vínculo mas está desengatado. O cavalo pode estar vinculado a uma ou várias carretas, mas não pode estar engatado em mais de uma.

 

O retorno deve ser o seguinte:

 

3 - CAVALO 3

 

Eu criei a consulta abaixo, mas não está certo pois trás o registro quando existe vínculo mais de uma vez:

 



SELECT
veiculo.codigo,
veiculo.descricao
FROM
veiculo
WHERE
(veiculo.tipo = '1') AND
((veiculo.codigo NOT IN (SELECT b.codigo_vinculo FROM veiculo as b WHERE (b.codigo_vinculo IS NOT NULL))) OR
(veiculo.codigo IN (SELECT b.codigo_vinculo FROM veiculo as b WHERE ((b.codigo_vinculo IS NOT NULL) AND (b.desengatado)))))


Agora deu "tilt" na cabeça e não estou conseguindo raciocinar. Alguém poderia me ajudar?

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Já resolveu?

 

Pelo que testei, esse código retornará o que precisa

 

SELECT * FROM (SELECT CODIGO,DESCRICAO,COD2,MIN(SEM_ENGATE) AS SEM_ENGATE FROM veiculoLEFT OUTER JOIN (SELECT CODIGO_VINCULO AS COD2,DESENGATADO AS SEM_ENGATE FROM veiculo WHERE TIPO = 2) AS S1 ON COD2 = CODIGOWHERE TIPO = 1GROUP BY CODIGO) AS S1 WHERE COD2 IS NULL OR SEM_ENGATE = 1;

 

Lembrando que fiz em mysql, então talvez precise de um ajuste nas colunas retornadas devido ao GROUP BY (já que o mysql retorna colunas que não estão no group by e que não usam função de agrupamento, e o sql server não (e talvez o postgree tb não))


Em SQLSERVER funcionou assim:

 

CREATE TABLE veiculo (  codigo integer,  tipo character(1),  descricao character varying(50),  codigo_vinculo integer,  desengatado int,  constraint pk_veiculo PRIMARY KEY (codigo),  constraint fk_veiculo_vinculo FOREIGN KEY (codigo_vinculo) REFERENCES veiculo (codigo)); INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (1, '1', 'CAVALO 1', NULL, NULL);INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (2, '1', 'CAVALO 2', NULL, NULL);INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (3, '1', 'CAVALO 3', NULL, NULL);INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (8, '1', 'CAVALO 4', NULL, NULL); INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (4, '2', 'CARRETA 1', NULL, 0);INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (5, '2', 'CARRETA 2', 1, 1);INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (6, '2', 'CARRETA 3', 2, 0);INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (7, '2', 'CARRETA 4', 1, 0);INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (9, '2', 'CARRETA 5', 8, 1);INSERT INTO veiculo (codigo, tipo, descricao, codigo_vinculo, desengatado) VALUES (10, '2', 'CARRETA 6', 8, 1); SELECT COD      ,DESCRICAO FROM (       SELECT CODIGO AS COD             ,COD2             ,MIN(SEM_ENGATE) AS SEM_ENGATE        FROM veiculo       LEFT OUTER JOIN (                         SELECT CODIGO_VINCULO AS COD2                               ,DESENGATADO AS SEM_ENGATE                          FROM veiculo                          WHERE TIPO = 2                       ) AS S1        ON COD2 = CODIGO       WHERE TIPO = 1       GROUP BY CODIGO,COD2     ) AS S1INNER JOIN veiculo ON CODIGO = CODWHERE COD2 IS NULL OR SEM_ENGATE = 1;
Link para o comentário
Compartilhar em outros sites

  • 3 semanas depois...

Não sei se está certo, mas no SELECT você não declarou a abreviação da tabela "veiculo", teria de colocar

 

"SELECT veiculo.item FROM veiculo veiculo...."

 

Victor, você está criando um ALIAS para a tabela, com o próprio nome dela. Isso ao meu ver é totalmente desnecessário, não existe essa obrigatoriedade e no fim das contas, isso mais atrapalha doq ajuda.

Link para o comentário
Compartilhar em outros sites

Victor, você está criando um ALIAS para a tabela, com o próprio nome dela. Isso ao meu ver é totalmente desnecessário, não existe essa obrigatoriedade e no fim das contas, isso mais atrapalha doq ajuda.

Estou falando que até onde sei de Banco de Dados, para usar igual ele usou "veiculo.codigo" teria de adicionar um alias à tabela no select por exemplo:

"SELECT ve.codigo,ve.nome FROM veiculos ve WHERE...." Também achei desnecessário nesse caso, afinal ele está usando apenas uma tabela. Mas foi o que notei rapidamente aqui. Me desculpe se estiver errado

 

 

@edit

 

Desculpe-me, agora que vi que não tinha erro de syntaxe, ignorem o que eu falei.

Link para o comentário
Compartilhar em outros sites

Estou falando que até onde sei de Banco de Dados, para usar igual ele usou "veiculo.codigo" teria de adicionar uma abreviação à tabela no select por exemplo:

"SELECT ve.codigo,ve.nome FROM veiculos ve WHERE...." Também achei desnecessário nesse caso, afinal ele está usando apenas uma tabela. Mas foi o que notei rapidamente aqui. Me desculpe se estiver errado

Não precisa usar abreviação, porque é o mesmo nome da tabela.

 

Então:

SELECT  veiculo.codigoFROM  veiculo

... é válido!

 

 

Agora se fosse:

SELECT  vei.codigoFROM  veiculo vei

... nesse caso teria que colocar o alias.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!