Apakah SQL memerlukan subquery?
Bayangkan implementasi yang cukup umum dari bahasa query terstruktur untuk database relasi. Karena struktur SELECT
pernyataan SQL kanonik sebenarnya cukup penting untuk membuat ini masuk akal, saya tidak menarik langsung ke aljabar relasional, tetapi Anda bisa membingkai ini dalam istilah-istilah tersebut dengan membuat batasan yang tepat pada bentuk ekspresi.
SQL SELECT
permintaan umumnya terdiri dari proyeksi (yang SELECT
bagian) beberapa jumlah JOIN
operasi (yang JOIN
bagian), beberapa jumlah SELECTION
operasi (di SQL, WHERE
klausa), dan kemudian set-bijaksana operasi ( UNION
, EXCEPT
, INTERSECT
, dll), diikuti oleh yang lain SELECT
Permintaan SQL .
Tabel yang disatukan dapat berupa hasil ekspresi yang dikomputasi; dengan kata lain, kita dapat memiliki pernyataan seperti:
SELECT t1.name, t2.address
FROM table1 AS t1
JOIN (SELECT id, address
FROM table2 AS t3
WHERE t3.id = t1.id) AS t2
WHERE t1.salary > 50,000;
Kami akan merujuk pada penggunaan tabel yang dihitung sebagai bagian dari kueri SQL sebagai subquery. Dalam contoh di atas, yang kedua (indentasi) SELECT
adalah subquery.
Bisakah semua query SQL ditulis sedemikian rupa agar tidak menggunakan subquery? Contoh di atas dapat:
SELECT t1.name, t2.address
FROM table1 AS t1
JOIN table2 AS t2
ON t1.id = t2.id
WHERE t1.salary > 50,000;
Contoh ini agak palsu, atau sepele, tetapi orang dapat membayangkan contoh-contoh di mana upaya yang jauh lebih mungkin diperlukan untuk memulihkan ekspresi yang setara. Dengan kata lain, apakah itu kasus untuk setiap query SQL dengan subqueries, ada query tanpa subqueries sehingga dan dijamin untuk menghasilkan hasil yang sama untuk tabel dasar yang sama? Biarkan kami membatasi kueri SQL ke formulir berikut:q ′ q q ′
SELECT <attribute>,
...,
<attribute>
FROM <a table, not a subquery>
JOIN <a table, not a subquery>
...
JOIN <a table, not a subquery>
WHERE <condition>
AND <condition>
...
AND <condition>
UNION
-or-
EXCEPT
-or-
<similar>
SELECT ...
Dan seterusnya. Saya pikir gabungan luar kiri dan kanan tidak menambahkan banyak, tetapi jika saya salah, silakan tunjukkan ... dalam hal apa pun, mereka juga merupakan permainan yang adil. Sejauh operasi ditetapkan, saya kira salah satu dari mereka baik-baik saja ... penyatuan, perbedaan, perbedaan simetris, persimpangan, dll ... apa pun yang bermanfaat. Apakah ada bentuk yang diketahui dimana semua pertanyaan SQL dapat dikurangi? Apakah ada di antara ini yang menghilangkan subkueri? Atau ada beberapa contoh di mana tidak ada kueri yang setara dan bebas subquery? Referensi dihargai ... atau demonstrasi (dengan bukti) bahwa mereka diperlukan atau tidak diperlukan akan fantastis. Terima kasih, dan maaf jika ini adalah hasil yang dirayakan (atau sepele) yang saya sangat tidak tahu.
sumber
select count(*) from (select id from sometable group by id having count(*)>1) d
. Karena itu termasukgroup by
saya belum menempatkan ini sebagai jawaban.ON
klausa diperlukan untukJOIN
s, meskipun produk silang diperoleh hanya dengan koma.Jawaban:
Ada beberapa kebingungan terminologi; blok permintaan dalam tanda kurung
disebut pandangan dalam . Sebuah subquery adalah blok permintaan dalam salah MANA atau klausa SELECT, misalnya
Dalam kedua kasus tersebut, pandangan bagian dalam atau subquery dapat digabungkan ke dalam proyek "flat" -rote-join. Subquery yang terkait dengan agregasi membuat unests ke tampilan dalam dengan pengelompokan, yang kemudian memasukkan ke dalam query datar.
Adapun aturan aljabar untuk optimisasi kueri, aljabar relasional diketahui di aksioma menjadi Relational Lattice yang menyederhanakan transformasi kueri seperti yang ditunjukkan di sana - sini .
sumber
Untuk menerjemahkan pernyataan Anda ke aljabar relasional, saya pikir itu bertanya:
Jawabannya adalah "Ya," dan ini merupakan optimasi kueri standar. Sejujurnya, saya tidak yakin bagaimana membuktikan ini dengan cara yang tidak meminta pertanyaan - itu hanya properti pilihan dan bergabung. Anda dapat berdebat secara induktif untuk menambahkan berapa pun lapisan kueri bersarang yang diinginkan.
Selain itu, Anda mungkin bertanya:
Sekali lagi jawabannya adalah ya, karena bergabung adalah asosiatif. Pernyataan serupa dapat dibuat tentang proyeksi juga.
Salah satu jenis "subquery" yang menurut saya tidak bisa "diratakan" adalah
with
. Salah satu cara untuk melihatnya adalah dengan mencatat bahwa jika Anda memilikiwith
pernyataan maka Anda dapat memiliki fungsi rekursif, yang tidak dapat ditulis tanpa menggunakan subquery.Jadi kesimpulannya: dalam kasus spesifik yang Anda sebutkan, tidak, SQL tidak perlu subquery, dan Anda dapat membuktikannya secara induktif. Secara umum, ada beberapa fitur yang memerlukan subquery.
sumber
with
diperkenalkan di SQL: 1999, dan membuat bahasa yang dihasilkan lebih ekspresif."Apakah subqueries menambah kekuatan ekspresif ke query SQL?"
Mereka melakukannya, setidaknya sebelum pengenalan KECUALI dalam bahasa SQL.
Sebelum pengenalan KECUALI, tidak ada cara apa pun untuk mengekspresikan perbedaan relasional atau semi-perbedaan dalam SQL tanpa menggunakan subqueries.
Saat ini, semua operator primitif "khas" aljabar relasional "dapat diekspresikan tanpa subqueries:
GABUNG ALAM dapat dilakukan melalui GABUNG ALAMI, atau GABUNG PADA
UNION dapat dilakukan melalui UNION.
MINUS dapat dilakukan melalui KECUALI
PROYEK / RENAME / PERBAIKAN dapat dilakukan melalui SELECT
RESTRICT dapat dilakukan melalui WHERE
relational literal dapat dilakukan melalui VALUES
penutupan dapat dilakukan melalui VALUES. dapat dilakukan melalui DENGAN rekursif
sumber