Usando SELECT na cláusula WHERE de outro SELECT


21

Eu fiz um rascunho de aplicativo remoto sobre a libpq para o PostrgreSQL . Ele se comporta bem, mas criei um perfil do funcionamento geral do aplicativo. Para cada resultado comercial final que produzo, chamo algo como a cláusula 40 select (over tcpip).

Tenho reminiscências do SQL Server lembrando-me de minimizar o número de interações entre meu aplicativo remoto e o banco de dados. Depois de analisar minhas seleções, acho que poderia reduzir esse número para 3 SELECTcláusulas, usando junções. Mas não me lembro da sintaxe para usar o resultado de um SELECTem outro SELECT.

Por exemplo:

SELECT * FROM individual
INNER JOIN publisher
ON individual.individual_id = publisher.individual_id
WHERE individual.individual_id = 'here I would like to use the results of a another select'

Este outro SELECTseria simplesmente do tipo:

SELECT identifier FROM another_table WHERE something='something'

Aqui está o layout simplificado das tabelas, recusado várias vezes para diferentes tipos de item ... (3 tipos totalmente diferentes, portanto, as 3 consultas SQL, se otimizadas).

table passage
  id_passage PK
  business_field_passage bytea

table item
  id_item PK
  id_passage FK
  business_field_item text

table item_detail
  id_item_detail PK
  id_item FK
  business_field_item_detail text
  image_content bytea

Existem vários id_itempara um id_passage.
Existem vários id_item_detailpara um id_item.

Como você escreveria isso?
Qual é o nome para descrever a ação de redirecionar uma seleção para outra (se houver)?



você está se referindo a 7.2.1.3. Subconsultas?
Stephane Rolland

Possivelmente sim, junto com a parte JOIN.
Dezso

Respostas:


30

É isso que você está buscando? Verifique se os campos que estão sendo comparados são comparáveis ​​(ou seja, os dois campos são numéricos, texto, booleano etc.).

SELECT * FROM Individual
INNER JOIN Publisher
ON Individual.IndividualId = Publisher.IndividualId
WHERE Individual.IndividualId = (SELECT someID FROM table WHERE blahblahblah)

Se você deseja selecionar com base em vários valores:

SELECT * FROM Individual
INNER JOIN Publisher
ON Individual.IndividualId = Publisher.IndividualId
WHERE Individual.IndividualId IN (SELECT someID FROM table WHERE blahblahblah)

pode ser tão direto assim? ainda funciona se SELECT someID FROM table WHERE blahblahblahtiver vários registros? Vou verificar isso agora.
precisa saber é o seguinte

Qual consulta está selecionando vários registros? Pode funcionar se você estiver selecionando vários registros, mas se você puder nos mostrar os layouts de sua tabela, isso nos ajudará a refinar a resposta.
Angry Spartan

1
WHERE Individual.IndividualId IN...parece bom.
Stephane Rolland

10

Você pode reescrever isso como outro JOIN. Isso normalmente é mais simples e rápido:

SELECT i.*, p.*
FROM   individual    i
JOIN   publisher     p USING (individualid)
JOIN   another_table a ON a.identifier = i.individualid
WHERE  a.something = 'something'

Também simplifiquei um pouco e acabei com a grafia gratuita dos identificadores do CamelCase.


1
Sim este. Eu morro um pouco por dentro sempre que vejo a sintaxe IN (SELECT ..).
Mark Storey-Smith

@ MarkStorey-Smith Você quer dizer que é mais do que simples e rápido: esse é um padrão de codificação sql para usar outro em joinvez de um in ( select...)Nesse caso, também devo atribuir a boa resposta a Erwin.
precisa saber é o seguinte

1
@StephaneRolland Se é mais rápido ou não, depende da plataforma e da versão. O SQL Server 2008 ou superior, por exemplo, gerará planos de execução idênticos para a sintaxe INNER JOIN e IN (SELECT ...). Não faço ideia se o mesmo se aplica ao PostgreSql. Além do desempenho, o estilo IN (SELECT ...) me deixa pensando se o autor compreendeu completamente a semântica e os conceitos do SQL. AngrySpartan respondeu à sua pergunta original corretamente. ErwinBrandstetter mostrou o caminho que você deve fazer :).
Mark Storey-Smith

6
@ MarkStorey-Smith: um JOIN nem sempre é equivalente a uma condição IN. A questão não é qual é mais rápida, a questão é qual está correta.
a_horse_with_no_name
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.