Использование 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.