Jawaban:
Mengapa Anda harus menempatkan kolom yang Anda buat sendiri (misalnya "pilih 1 sebagai nomor") setelah MEMILIKI dan tidak DI MANA di MySQL?
WHERE
diterapkan sebelumnya GROUP BY
, HAVING
diterapkan setelah (dan dapat memfilter pada agregat).
Secara umum, Anda dapat mereferensikan alias di kedua klausa ini, tetapi MySQL
membolehkan SELECT
alias level referensi di GROUP BY
, ORDER BY
dan 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 WHERE
klausa kemungkinan besar akan lebih efisien.
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.
SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
...HAVING clause can use both column and alias.
ke ...HAVING clause can use either column or alias.
dan ubah ...WHERE clause will be more effective
ke...WHERE clause will be more efficient
Perbedaan utama adalah bahwa WHERE
tidak dapat digunakan pada item yang dikelompokkan (seperti SUM(number)
) sedangkan HAVING
bisa.
Alasannya adalah WHERE
dilakukan sebelum pengelompokan dan HAVING
dilakukan setelah pengelompokan selesai.
HAVING
digunakan untuk memfilter pada agregasi di blog Anda GROUP BY
.
Misalnya, untuk memeriksa nama duplikat:
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
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.*/
WHERE
dan HAVING
.
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 ...).".
Memiliki hanya digunakan dengan agregasi tetapi di mana dengan pernyataan non agregasi Jika Anda memiliki kata di mana meletakkannya sebelum agregasi (dikelompokkan berdasarkan)