Bisakah Anda menggunakan alias di klausa WHERE di mysql?

121

Saya perlu menggunakan alias di klausa WHERE, tetapi itu terus memberi tahu saya bahwa itu adalah kolom yang tidak diketahui. Apakah ada cara untuk mengatasi masalah ini? Saya perlu memilih rekaman yang memiliki peringkat lebih tinggi dari x. Peringkat dihitung sebagai alias berikut:

sum(reviews.rev_rating)/count(reviews.rev_id) as avg_rating
dreftymac.dll
sumber

Jawaban:

229

Anda dapat menggunakan klausa HAVING, yang dapat melihat alias, misalnya

 HAVING avg_rating>5

tetapi dalam klausa where Anda harus mengulangi ekspresi Anda, misalnya

 WHERE (sum(reviews.rev_rating)/count(reviews.rev_id))>5

TAPI! Tidak semua ekspresi diizinkan - menggunakan fungsi agregat seperti SUM tidak akan berfungsi, dalam hal ini Anda harus menggunakan klausa HAVING.

Dari Manual MySQL :

Tidak diperbolehkan merujuk ke alias kolom dalam klausa WHERE, karena nilai kolom mungkin belum ditentukan ketika klausa WHERE dijalankan. Lihat Bagian B.1.5.4, “Masalah dengan Alias ​​Kolom” .

Paul Dixon
sumber
1
Jika saya mengulangi ekspresi tersebut, saya akan diberi tahu: "penggunaan fungsi grup yang tidak valid"
3
Telah menulis ulang untuk membuatnya lebih jelas bahwa fungsi agregasi tidak diizinkan
Paul Dixon
Penjelasan yang bagus, khususnya. bagian "tapi di mana klausa ... ulangi .."
th3an0maly
4
Ini adalah jawaban yang bagus, tetapi harap pertimbangkan implikasi kinerja karena HAVINGdijalankan setelah data diambil dan WHEREdijalankan sebelumnya.
StockB
Anda tidak dapat menggunakan fungsi agregat dalam klausa WHERE. Klausa WHERE hanya memfilter baris satu per satu, bukan seluruh grup.
Bill Karwin
33

Entah apakah ini berfungsi di mysql tetapi menggunakan sqlserver Anda juga bisa membungkusnya seperti:

select * from (
  -- your original query
  select .. sum(reviews.rev_rating)/count(reviews.rev_id) as avg_rating 
  from ...) Foo
where Foo.avg_rating ...
Torbjörn Gyllebring
sumber
6

Pertanyaan ini cukup lama dan satu jawaban sudah mendapatkan 160 suara ...

Namun saya akan memperjelas ini: Pertanyaannya sebenarnya bukan tentang apakah nama alias dapat digunakan dalam WHEREklausa.

sum(reviews.rev_rating) / count(reviews.rev_id) as avg_rating

adalah agregasi. Dalam WHEREklausa kami membatasi rekaman yang kami inginkan dari tabel dengan melihat nilainya. sum(reviews.rev_rating)dan count(reviews.rev_id), bagaimanapun, bukanlah nilai yang kita temukan dalam catatan; itu adalah nilai yang hanya kita dapatkan setelah mengumpulkan catatan.

Jadi WHEREtidak pantas. Kami membutuhkan HAVING, karena kami ingin membatasi baris hasil setelah agregasi. Tidak mungkin

WHERE avg_rating > 10

maupun

WHERE sum(reviews.rev_rating) / count(reviews.rev_id) > 10

karenanya.

HAVING sum(reviews.rev_rating) / count(reviews.rev_id) > 10

di sisi lain dimungkinkan dan sesuai dengan standar SQL. Sedangkan

HAVING avg_rating > 10

hanya mungkin di MySQL. Ini bukan SQL yang valid menurut standar, karena SELECTklausa seharusnya dijalankan setelahnya HAVING. Dari dokumen MySQL:

Ekstensi MySQL lain untuk SQL standar memungkinkan referensi di klausa HAVING ke ekspresi alias di daftar pilih.

Ekstensi MySQL mengizinkan penggunaan alias di klausa HAVING untuk kolom agregat

https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

Thorsten Kettner
sumber
0

Jika kueri Anda statis, Anda dapat menetapkannya sebagai tampilan, lalu Anda dapat menggunakan alias tersebut di klausa where saat membuat kueri tampilan.

alpere
sumber
0
SELECT * FROM (SELECT customer_Id AS 'custId', gender, age FROM customer
    WHERE  gender = 'F') AS c
WHERE c.custId = 100;
anson
sumber