Использование SELECT в предложении WHERE другого SELECT

21

Я сделал проект удаленного приложения поверх libpq для PostrgreSQL . Это ведет себя хорошо, но я представил общее функционирование приложения. Для каждого конечного результата, который я получаю, случается так, что я вызываю что-то вроде предложения 40 select (через tcpip).

У меня есть воспоминания от SQL-Server, напоминающие мне, чтобы минимизировать количество взаимодействий между моим удаленным приложением и базой данных. Проанализировав мои выборки, я думаю, что смогу сократить это число до 3-х SELECT, используя объединения. Но я не помню синтаксис для использования результата a SELECTв другом SELECT.

Например:

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'

Этот другой SELECTбудет просто такого рода:

SELECT identifier FROM another_table WHERE something='something'

Вот упрощенная компоновка таблиц, несколько раз отклоненная для разных типов элементов ... (3 абсолютно разных типа, следовательно, 3 запроса SQL, если они оптимизированы).

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

Есть несколько id_itemдля одного id_passage.
Есть несколько id_item_detailдля одного id_item.

Как бы вы это написали?
Как называется действие по перенаправлению одного выбора в другой (если есть)?

Стефан Роллан
источник
Вы имеете в виду 7.2.1.3. Подзапросы?
Стефан Роллан
Возможно, да, вместе с частью JOIN.
Дезсо

Ответы:

30

Это то, к чему вы стремитесь? Убедитесь, что сравниваемые поля сопоставимы (т. Е. Оба поля являются числовыми, текстовыми, логическими и т. Д.).

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

Если вы хотите выбрать на основе нескольких значений:

SELECT * FROM Individual
INNER JOIN Publisher
ON Individual.IndividualId = Publisher.IndividualId
WHERE Individual.IndividualId IN (SELECT someID FROM table WHERE blahblahblah)
Злой Спартанец
источник
это может быть так просто? это все еще работает, если SELECT someID FROM table WHERE blahblahblahесть несколько записей? Я проверю это прямо сейчас.
Стефан Роллан
Какой запрос выбирает несколько записей? Это может сработать, если вы выбираете несколько записей, но если бы вы могли показать нам свои таблицы, которые помогут нам уточнить ответ.
Злой Спартанец
1
WHERE Individual.IndividualId IN...выглядит хорошо.
Стефан Роллан
10

Вы можете просто переписать это как другое JOIN. Обычно это самый простой и быстрый способ:

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

Я также несколько упростил и покончил с необоснованным написанием идентификаторов CamelCase.

Эрвин Брандштеттер
источник
1
Да это. Я умираю немного внутри, когда вижу синтаксис IN (SELECT ..).
Марк Стори-Смит
@ MarkStorey-Smith. Вы имеете в виду, что это более чем просто и быстрее: это стандарт SQL-кодирования для использования другого joinвместо ... in ( select...)В таком случае я должен также приписать хороший ответ Эрвину.
Стефан Роллан
1
@StephaneRolland Будет ли он быстрее или нет, будет зависеть от платформы и версии. Например, SQL Server 2008+ будет генерировать идентичные планы выполнения для синтаксиса INNER JOIN и IN (SELECT ...). Не знаю, применимо ли это к PostgreSql. Помимо производительности, стиль IN (SELECT ...) заставляет меня задуматься, полностью ли автор понял семантику и концепции SQL. AngrySpartan правильно ответил на ваш оригинальный вопрос. ErwinBrandstetter показал вам, как вы должны это сделать :).
Марк Стори-Смит
6
@ MarkStorey-Smith: JOIN не всегда эквивалентен условию IN. Вопрос не в том, какой из них быстрее, а в том, какой из них правильный.
a_horse_with_no_name