Menggunakan SELECT dalam klausa WHERE dari SELECT lain

21

Saya telah membuat rancangan aplikasi jarak jauh di atas libpq untuk PostrgreSQL . Itu berperilaku baik, tetapi saya telah membuat profil fungsi aplikasi secara umum. Untuk setiap hasil bisnis akhir yang saya hasilkan, kebetulan saya menyebut sekitar 40 klausa pilih (lebih dari tcpip).

Saya memiliki kenangan dari SQL-Server yang mengingatkan saya untuk meminimalkan jumlah interaksi antara aplikasi jarak jauh saya dan database. Setelah menganalisis pilihan saya, saya pikir saya bisa mengurangi jumlah ini menjadi 3 SELECTklausa, menggunakan gabungan. Tapi saya tidak ingat sintaks untuk menggunakan hasil dari yang SELECTlain SELECT.

Misalnya:

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'

Yang lain ini SELECTakan menjadi sejenis:

SELECT identifier FROM another_table WHERE something='something'

Berikut adalah tata letak tabel yang disederhanakan, menolak beberapa kali untuk item_types yang berbeda ... (3 jenis yang sama sekali berbeda, maka 3 kueri SQL jika dioptimalkan).

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

Ada beberapa id_itemuntuk satu id_passage.
Ada beberapa id_item_detailuntuk satu id_item.

Bagaimana Anda menulis itu?
Apa nama untuk menggambarkan tindakan pengalihan satu pilih ke yang lain (jika ada)?

Stephane Rolland
sumber
apakah Anda mengacu pada 7.2.1.3. Subquery?
Stephane Rolland
Mungkin ya, bersama dengan bagian GABUNG.
dezso

Jawaban:

30

Apakah ini yang Anda tuju? Pastikan bidang yang dibandingkan sebanding (yaitu kedua bidang itu numerik, teks, boolean, dll).

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

Jika Anda ingin memilih berdasarkan beberapa nilai:

SELECT * FROM Individual
INNER JOIN Publisher
ON Individual.IndividualId = Publisher.IndividualId
WHERE Individual.IndividualId IN (SELECT someID FROM table WHERE blahblahblah)
Spartan Marah
sumber
mungkinkah itu lurus ke depan ?? apakah masih berfungsi jika SELECT someID FROM table WHERE blahblahblahmemiliki banyak catatan? Aku akan memeriksanya sekarang.
Stephane Rolland
Query mana yang memilih banyak record? Ini bisa bekerja jika Anda memilih beberapa catatan, tetapi jika Anda bisa menunjukkan kepada kami tata letak meja Anda yang akan membantu kami memperbaiki jawabannya.
Angry Spartan
1
WHERE Individual.IndividualId IN...kelihatan bagus.
Stephane Rolland
10

Anda bisa menulis ulang itu sebagai yang lain JOIN. Ini biasanya paling sederhana dan tercepat:

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

Saya juga agak menyederhanakan dan menghilangkan ejaan CamelCase gratisan.

Erwin Brandstetter
sumber
1
Iya ini. Saya mati sedikit di dalam setiap kali saya melihat sintaks IN (SELECT ..).
Mark Storey-Smith
@ MarkStorey-Smith Maksud Anda lebih sederhana dan lebih cepat: ini adalah standar pengkodean sql untuk menggunakan yang lain joinalih-alih in ( select...)dalam kasus tersebut, saya juga harus mengaitkan jawaban yang baik dengan Erwin.
Stephane Rolland
1
@StephaneRolland Apakah lebih cepat atau tidak tergantung platform dan versi. SQL Server 2008+ misalnya akan menghasilkan rencana eksekusi yang identik untuk sintaks INNER JOIN dan IN (SELECT ...). Tidak tahu apakah hal yang sama berlaku untuk PostgreSql. Selain kinerja, gaya IN (SELECT ...) membuat saya bertanya-tanya apakah penulis telah sepenuhnya memahami semantik dan konsep SQL. AngrySpartan telah menjawab pertanyaan awal Anda dengan benar. ErwinBrandstetter telah menunjukkan kepada Anda cara Anda harus melakukannya :).
Mark Storey-Smith
6
@ MarkStorey-Smith: GABUNG tidak selalu setara dengan kondisi IN. Pertanyaannya bukan yang mana yang lebih cepat, pertanyaannya adalah yang mana yang benar.
a_horse_with_no_name