Ringkasan
Tidak ada alasan logis mengapa hal itu tidak dapat dilakukan, tetapi manfaatnya kecil dan ada beberapa perangkap yang mungkin tidak segera terlihat.
Hasil penelitian
Saya melakukan riset dan menemukan beberapa informasi yang baik. Berikut ini adalah kutipan langsung dari sumber utama yang dapat diandalkan (yang ingin tetap anonim) pada 2012-08-09 17:49 GMT:
Ketika SQL pertama kali ditemukan, ia tidak memiliki alias dalam klausa SELECT. Ini adalah kelemahan serius yang diperbaiki ketika bahasa tersebut dibakukan oleh ANSI pada sekitar tahun 1986.
Bahasa itu dimaksudkan untuk "non-prosedural" - dengan kata lain, untuk menggambarkan data yang Anda inginkan tanpa menentukan cara menemukannya. Jadi, sejauh yang saya tahu, tidak ada alasan mengapa implementasi SQL tidak dapat menguraikan seluruh permintaan sebelum memprosesnya, dan mengizinkan alias untuk didefinisikan di mana saja dan digunakan di mana-mana. Misalnya, saya tidak melihat alasan mengapa kueri berikut tidak valid:
select name, salary + bonus as pay
from employee
where pay > 100000
Meskipun saya pikir ini adalah permintaan yang masuk akal, beberapa sistem berbasis SQL dapat memperkenalkan pembatasan penggunaan alias untuk beberapa alasan terkait implementasi. Saya tidak terkejut mendengar bahwa SQL Server melakukan ini.
Saya tertarik dalam penelitian lebih lanjut tentang standar SQL-86 dan mengapa DBMS modern tidak mendukung alias digunakan kembali, tetapi belum punya waktu untuk melakukannya. Sebagai permulaan, saya tidak tahu di mana mendapatkan dokumentasi atau bagaimana mencari tahu siapa yang sebenarnya menjadi panitia. Adakah yang bisa membantu? Saya juga ingin tahu lebih banyak tentang produk Sybase asli yang berasal dari SQL Server.
Dari penelitian ini dan beberapa pemikiran lebih lanjut, saya menjadi curiga bahwa menggunakan alias di klausa lain, walaupun sangat mungkin, tidak pernah menjadi prioritas yang tinggi untuk produsen DBMS dibandingkan dengan fitur bahasa lainnya. Karena itu tidak terlalu banyak kendala, yang dengan mudah dikerjakan oleh penulis kueri, menempatkan upaya ke dalamnya atas kemajuan lain tidak optimal. Selain itu, itu akan menjadi hak milik karena jelas bukan bagian dari standar SQL (meskipun saya menunggu untuk mengetahui lebih lanjut tentang itu) dan dengan demikian akan menjadi perbaikan kecil, melanggar kompatibilitas SQL antara DBMSes. Sebagai perbandingan, CROSS APPLY
(yang benar-benar tidak lebih dari tabel turunan yang memungkinkan referensi luar) adalah perubahan besar, bahwa sementara kepemilikan menawarkan kekuatan ekspresif yang luar biasa tidak mudah dilakukan dengan cara lain.
Masalah Dengan Menggunakan Alias Di Mana Saja
Jika Anda mengizinkan item SELECT untuk dimasukkan ke dalam klausa WHERE, Anda tidak hanya bisa meledakkan kompleksitas kueri (dan dengan demikian kompleksitas menemukan rencana eksekusi yang baik) dimungkinkan untuk menghasilkan hal-hal yang sama sekali tidak masuk akal. Mencoba:
SELECT X + 5 Y FROM MyTable WHERE Y = X
Bagaimana jika MyTable sudah memiliki kolom Y, yang mana yang dimaksud dengan klausa WHERE? Solusinya adalah dengan menggunakan CTE atau tabel turunan, yang dalam kebanyakan kasus tidak memerlukan biaya tambahan tetapi mencapai hasil akhir yang sama. CTE dan tabel turunan setidaknya menegakkan resolusi ambiguitas dengan mengizinkan alias hanya digunakan satu kali.
Juga, tidak menggunakan alias dalam klausa FROM masuk akal. Anda tidak dapat melakukan ini:
SELECT
T3.ID + (SELECT Min(Interval) FROM Intervals WHERE IntName = 'T') CalcID
FROM
Table1 T
INNER JOIN Table2 T2
ON T2.ID = CalcID
INNER JOIN Table3 T3
ON T2.ID = T3.ID
Itu referensi melingkar (dalam arti bahwa T2 diam-diam merujuk pada nilai dari T3, sebelum tabel itu disajikan dalam daftar BERGABUNG), dan sangat sulit untuk dilihat. Bagaimana dengan yang ini:
INSERT dbo.FinalTransaction
SELECT
newid() FinalTransactionGUID,
'GUID is: ' + Convert(varchar(50), FinalTransactionGUID) TextGUID,
T.*
FROM
dbo.MyTable T
Seberapa besar Anda ingin bertaruh bahwa fungsi newid () akan dimasukkan ke dalam rencana eksekusi dua kali, benar-benar secara tak terduga membuat dua kolom menunjukkan nilai yang berbeda? Bagaimana bila kueri di atas digunakan level N jauh di CTE atau tabel turunan. Saya jamin masalahnya lebih buruk dari yang bisa Anda bayangkan. Ada sudah masalah inkonsistensi serius ketika hal-hal yang dievaluasi hanya sekali atau pada titik apa dalam rencana permintaan, dan Microsoft telah mengatakan tidak akan memperbaikibeberapa di antaranya karena mereka mengekspresikan aljabar kueri dengan benar - jika seseorang mendapatkan hasil yang tidak terduga, pisahkan kueri menjadi beberapa bagian. Membiarkan referensi berantai, mendeteksi referensi melingkar melalui rantai yang berpotensi sangat lama – ini adalah masalah yang cukup rumit. Kenalkan paralelisme dan Anda akan mendapatkan mimpi buruk.
Catatan: Menggunakan alias di WHERE atau GROUP BY tidak akan membuat perbedaan pada masalah dengan fungsi seperti newid () atau rand ().
Cara SQL Server untuk membuat ekspresi yang dapat digunakan kembali
CROSS APPLY / OUTER APPLY adalah salah satu cara di SQL Server untuk membuat ekspresi yang dapat digunakan di tempat lain dalam kueri (tidak lebih awal dari klausa FROM):
SELECT
X.CalcID
FROM
Table1 T
INNER JOIN Table3 T3
ON T.ID = T3.ID
CROSS APPLY (
SELECT
T3.ID + (SELECT Min(Interval) FROM Intervals WHERE IntName = 'T') CalcID
) X
INNER JOIN Table2 T2
ON T2.ID = X.CalcID
Ini melakukan dua hal:
- Membuat semua ekspresi di CROSS APPLY mendapatkan "namespace" (alias tabel, di sini, X) dan menjadi unik di dalam namespace itu.
- Menjadikannya jelas di mana-mana tidak hanya bahwa CalcID berasal dari X, tetapi juga menjelaskan mengapa Anda tidak dapat menggunakan apa pun dari X saat bergabung dengan tabel T1 dan T3, karena X belum diperkenalkan.
Saya sebenarnya cukup suka LINTAS BERLAKU. Itu telah menjadi teman saya yang setia, dan saya menggunakannya setiap saat. Perlu sebagian UNPIVOT (yang akan membutuhkan PIVOT / UNPIVOT atau UNPIVOT / PIVOT menggunakan sintaksis asli)? Dikerjakan dengan SALIB BERLAKU. Perlu nilai terhitung yang akan digunakan kembali berkali-kali? Selesai Perlu menerapkan perintah eksekusi secara kaku untuk panggilan melalui server yang ditautkan? Dilakukan dengan peningkatan kecepatan yang menjerit. Hanya perlu satu jenis baris dibagi menjadi 2 baris atau dengan kondisi tambahan? Selesai
Jadi, paling tidak, dalam DBMS SQL Server 2005 dan yang lebih tinggi, Anda tidak memiliki alasan lebih lanjut untuk komplain: CROSS BERLAKU adalah cara Anda KERING dengan cara yang Anda inginkan.