Використання SELECT у пункті WHERE іншого SELECT


21

Я зробив проект віддаленого додатку поверх libpq для PostrgreSQL . Він поводиться добре, але я профілював загальне функціонування програми. Кожен кінцевий бізнес-результат, який я створюю, буває, що я називаю щось на зразок 40-го вибору (понад tcpip).

У мене є нагадування від SQL-сервера, що нагадує мені мінімізувати кількість взаємодій між моєю віддаленою програмою та базою даних. Проаналізувавши свій вибір, я думаю, що міг би скоротити цю кількість до 3-х SELECTзастережень, використовуючи приєднання. Але я не пам'ятаю синтаксис для використання результату 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. Підзапити?
Стефан Ролланд

Можливо, так, разом із частиною ПРИЄДНАЙТЕСЬ.
dezso

Відповіді:


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: ПРИЄДНАННЯ не завжди еквівалентно умові IN. Питання не в тому, який з них швидше, а в тому, який з них правильний.
a_horse_with_no_name
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.