DI MANA vs MEMILIKI

247

Mengapa Anda perlu menempatkan kolom yang Anda buat sendiri (misalnya select 1 as "number") setelah HAVINGdan tidak WHEREdi MySQL?

Dan apakah ada kelemahan daripada melakukan WHERE 1(menulis seluruh definisi, bukan nama kolom)?

balo
sumber

Jawaban:

323

Mengapa Anda harus menempatkan kolom yang Anda buat sendiri (misalnya "pilih 1 sebagai nomor") setelah MEMILIKI dan tidak DI MANA di MySQL?

WHEREditerapkan sebelumnya GROUP BY, HAVINGditerapkan setelah (dan dapat memfilter pada agregat).

Secara umum, Anda dapat mereferensikan alias di kedua klausa ini, tetapi MySQLmembolehkan SELECTalias level referensi di GROUP BY, ORDER BYdan HAVING.

Dan apakah ada kerugian selain melakukan "DI MANA 1" (menulis seluruh definisi bukannya nama kolom)

Jika ekspresi Anda yang dihitung tidak mengandung agregat, memasukkannya ke dalam WHEREklausa kemungkinan besar akan lebih efisien.

Quassnoi
sumber
289

Semua jawaban lain untuk pertanyaan ini tidak menyentuh titik kunci.

Asumsikan kita memiliki tabel:

CREATE TABLE `table` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `value` int(10) unsigned NOT NULL,
 PRIMARY KEY (`id`),
 KEY `value` (`value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Dan memiliki 10 baris dengan id dan nilai dari 1 hingga 10:

INSERT INTO `table`(`id`, `value`) VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5),(6, 6),(7, 7),(8, 8),(9, 9),(10, 10);

Coba 2 pertanyaan berikut:

SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows

Anda akan mendapatkan hasil yang persis sama, Anda dapat melihat klausa HAVING dapat bekerja tanpa klausa GROUP BY.


Inilah perbedaannya:

SELECT `value` v FROM `table` WHERE `v`>5;

Kesalahan # 1054 - Kolom tidak dikenal 'v' in 'where clause'

SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows

Klausa WHERE memungkinkan suatu kondisi untuk menggunakan kolom tabel apa saja, tetapi tidak dapat menggunakan alias atau fungsi agregat. Klausa HAVING memungkinkan suatu kondisi untuk menggunakan kolom (!) Yang dipilih, alias atau fungsi agregat.

Ini karena klausa WHERE menyaring data sebelum pilih, tetapi klausa HAVING menyaring data yang dihasilkan setelah pilih.

Jadi, letakkan kondisi di WHERE klausa akan lebih efisien jika Anda memiliki banyak baris dalam sebuah tabel.

Coba EXPLAIN untuk melihat perbedaan utama:

EXPLAIN SELECT `value` v FROM `table` WHERE `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key   | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
|  1 | SIMPLE      | table | range | value         | value | 4       | NULL |    5 | Using where; Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+

EXPLAIN SELECT `value` v FROM `table` having `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key   | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
|  1 | SIMPLE      | table | index | NULL          | value | 4       | NULL |   10 | Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+

Anda dapat melihat WHERE atau HAVING menggunakan indeks, tetapi barisnya berbeda.

Tenggelam dalam ikan
sumber
32
Saya menghargai bahwa Anda menyebutkan MENJELASKAN!
paiego
Karena HAVING filter klausa data setelah pilih, klausa WHERE akan lebih efektif. Jadi jika ini benar, kapan kita harus menggunakan MEMILIKI bukannya DI MANA?
grep
5
@ grep Jika Anda harus memfilter data setelah memilih, Anda perlu memiliki klausa HAVING, biasanya kami menggunakannya dengan klausa GROUP BY, misalnya: SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
Fishdrowned
1
Pos luar biasa. Beberapa klarifikasi yang disarankan: Ubah ...HAVING clause can use both column and alias.ke ...HAVING clause can use either column or alias.dan ubah ...WHERE clause will be more effectiveke...WHERE clause will be more efficient
rmirabelle
2
Klausa HAVING ditambahkan ke SQL karena kata kunci WHERE tidak dapat digunakan dengan fungsi agregat.
Shashank Vivek
62

Perbedaan utama adalah bahwa WHEREtidak dapat digunakan pada item yang dikelompokkan (seperti SUM(number)) sedangkan HAVINGbisa.

Alasannya adalah WHEREdilakukan sebelum pengelompokan dan HAVINGdilakukan setelah pengelompokan selesai.

David Brunelle
sumber
39

HAVINGdigunakan untuk memfilter pada agregasi di blog Anda GROUP BY.

Misalnya, untuk memeriksa nama duplikat:

SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
Kevin McKelvin
sumber
1
Memang benar untuk beberapa yang masih ada. Anda masih dapat menempatkan seluruh 'Di mana' Anda dalam klausa memiliki.
David Brunelle
8

Ini 2 akan terasa sama seperti pertama karena keduanya digunakan untuk mengatakan tentang suatu kondisi untuk menyaring data. Meskipun kita dapat menggunakan 'memiliki' sebagai pengganti 'di mana' dalam hal apa pun, ada beberapa contoh ketika kita tidak dapat menggunakan 'di mana' alih-alih 'memiliki'. Ini karena dalam kueri pemilihan, 'di mana' menyaring data sebelum 'pilih' sementara 'memiliki' menyaring data setelah 'pilih'. Jadi, ketika kita menggunakan nama alias yang sebenarnya tidak ada dalam database, 'di mana' tidak dapat mengidentifikasi mereka tetapi 'memiliki' bisa.

Mis: biarkan tabel Siswa berisi student_id, nama, ulang tahun, alamat. Asumsikan ulang tahun bertipe tanggal.

SELECT * FROM Student WHERE YEAR(birthday)>1993; /*this will work as birthday is in database.if we use having in place of where too this will work*/

SELECT student_id,(YEAR(CurDate())-YEAR(birthday)) AS Age FROM Student HAVING Age>20; 
/*this will not work if we use ‘where’ here, ‘where’ don’t know about age as age is defined in select part.*/
Nuwantha
sumber
1
Contoh kehidupan nyata ini sepenuhnya menjelaskan perbedaan antara WHEREdan HAVING.
WM
Jelas menunjukkan perbedaan antara Memiliki dan di mana. Terima kasih.
MarcoZen
3

WHERE menyaring sebelum data dikelompokkan, dan MEMILIKI filter setelah data dikelompokkan. Ini adalah perbedaan penting; baris yang dihilangkan oleh klausa WHERE tidak akan dimasukkan dalam grup. Ini bisa mengubah nilai yang dihitung yang, pada gilirannya (= sebagai hasilnya) dapat memengaruhi kelompok mana yang difilter berdasarkan penggunaan nilai-nilai tersebut dalam klausa HAVING .

Dan berlanjut,

MEMILIKI sangat mirip dengan DIMANA bahwa kebanyakan DBMS memperlakukan mereka sebagai hal yang sama jika tidak ada GROUP BY yang ditentukan. Namun demikian, Anda harus membuat perbedaan itu sendiri. Gunakan HAVING hanya dalam hubungannya dengan klausa GROUP BY . Gunakan WHERE untuk pemfilteran tingkat baris standar.

Kutipan Dari: Forta, Ben. "Sams Teach Yourself SQL dalam 10 Menit (Edisi ke-5) (Sams Teach Yourself ...).".

snr
sumber
1

Memiliki hanya digunakan dengan agregasi tetapi di mana dengan pernyataan non agregasi Jika Anda memiliki kata di mana meletakkannya sebelum agregasi (dikelompokkan berdasarkan)

Hos Mercury
sumber