Dalam SQL, sejauh yang saya tahu, urutan pemrosesan kueri logis, yang merupakan urutan interpretasi konseptual, dimulai dengan FROM dengan cara berikut:
- DARI
- DIMANA
- KELOMPOK OLEH
- MEMILIKI
- PILIH
- DIPESAN OLEH
Mengikuti daftar ini mudah untuk melihat mengapa Anda tidak dapat memiliki alias SELECT dalam klausa WHERE, karena alias belum dibuat. T-SQL (SQL Server) mengikuti ini dengan ketat dan Anda tidak dapat menggunakan alias SELECT sampai Anda telah melewati SELECT.
Tetapi dalam MySQL dimungkinkan untuk menggunakan alias SELECT dalam klausa HAVING meskipun harus (secara logis) diproses sebelum klausa SELECT. Bagaimana ini bisa terjadi?
Untuk memberi contoh:
SELECT YEAR(orderdate), COUNT(*) as Amount
FROM Sales.Orders
GROUP BY YEAR(orderdate)
HAVING Amount>1;
Pernyataan ini tidak valid dalam T-SQL (karena HAVING mengacu pada alias SELECT Amount
) ...
Msg 207, Level 16, State 1, Line 5
Invalid column name 'Amount'.
... tetapi berfungsi dengan baik di MySQL.
Berdasarkan ini, saya bertanya-tanya:
- Apakah MySQL mengambil jalan pintas dalam aturan SQL untuk membantu pengguna? Mungkin menggunakan semacam pra-analisis?
- Atau apakah MySQL menggunakan urutan interpretasi konseptual yang berbeda dari yang saya ikuti, meskipun semua RDBMS mengikuti?
sumber
SELECT C, ROW_NUMBER() OVER (ORDER BY X) AS RN FROM T GROUP BY C HAVING RN = 1
akan bermasalah sebagaiROW_NUMBER
berjalan setelah ituHAVING
SELECT @rownum:=@rownum + 1 as row ...
. Mungkin alasan mengapa mereka mendukung alias SELECT adalah karena mereka dapat, karena fakta bahwa mereka tidak mendukung hal-hal yang membuat tidak mungkin ... siapa yang tahu? :)HAVING
danSELECT
klausa dapat dipertukarkan. Jadi, tidak ada ambiguitas dalam melakukan ini dan dapat menyederhanakan tampilan kode ketika ada ekspresi mengerikan diSELECT
.distincts
) ... dengan hasilAlias in the Having
yang sama meskipunExplain
. Jadi beberapa variasi dengan Pengoptimal sedang terjadi.Jawaban:
Nah ketika Anda memiliki pertanyaan semacam ini, sumber informasi IMHO terbaik adalah dokumentasi MySQL. Sekarang to the point. Ini adalah perilaku ekstensi MySql
GROUP BY
yang diaktifkan secara default.Jika Anda menginginkan perilaku standar, Anda dapat menonaktifkan ekstensi ini dengan
sql_mode
ONLY_FULL_GROUP_BY
Jika Anda mencoba menjalankan kueri yang disebutkan di atas dalam
ONLY_FULL_GROUP_BY
sql_mode Anda akan mendapatkan pesan kesalahan berikut:Ini demo SQLFiddle
Karena itu terserah Anda bagaimana mengkonfigurasi dan menggunakan instance MySQL Anda.
sumber
ORDER BY
, misalnya, mungkin benar-benar ditangani jauh lebih awal daripada secara teoritis, jika pengoptimal menemukan bahwa baris pada awalnya dapat dibaca dalam urutan dari indeks yang sudah dalam urutan yang diinginkan.Pertanyaan bagus.
Saya pikir Anda harus menjalankan querys ini
dan periksa bagaimana kueri ditulis ulang. saya cukup yakin pengoptimal permintaan mengganti Jumlah dengan COUNT (*)
Seperti halnya dengan
setelah query optimizer nya seperti ini.
sumber