Odpowiedzi:
Dlaczego musisz umieścić kolumny, które sam tworzysz (na przykład „wybierz 1 jako liczbę”) po HAVINGU, a nie GDZIE w MySQL?
WHEREjest stosowany przed GROUP BY, HAVINGjest stosowany po (i może filtrować według agregatów).
Ogólnie rzecz biorąc, można odwoływać aliasy w żadnym z tych klauzul, ale MySQLpozwala na przedstawieniu SELECTaliasy w poziomie GROUP BY, ORDER BYa HAVING.
I czy są jakieś wady zamiast robić „GDZIE 1” (zapisywanie całej definicji zamiast nazwy kolumny)
Jeśli obliczone wyrażenie nie zawiera żadnych agregatów, umieszczenie go w WHEREklauzuli najprawdopodobniej będzie bardziej wydajne.
Wszystkie inne odpowiedzi na to pytanie nie trafiły w kluczowy punkt.
Załóżmy, że mamy 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
I mają 10 wierszy o identyfikatorze i wartości od 1 do 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);
Wypróbuj następujące 2 zapytania:
SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows
Otrzymasz dokładnie takie same wyniki, możesz zobaczyć, że klauzula HAVING może działać bez klauzuli GROUP BY.
Oto różnica:
SELECT `value` v FROM `table` WHERE `v`>5;
Błąd # 1054 - Nieznana kolumna „v” w „klauzula”
SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows
Klauzula WHERE zezwala warunkowi na użycie dowolnej kolumny tabeli, ale nie może używać aliasów ani funkcji agregujących. Klauzula HAVING pozwala warunkowi na użycie wybranej (!) Kolumny, aliasu lub funkcji agregującej.
Jest tak, ponieważ klauzula WHERE filtruje dane przed wyborem, ale klauzula HAVING filtruje dane wynikowe po wybraniu.
Więc wstaw warunki do klauzuli WHERE będą bardziej wydajne, jeśli masz wiele wielu wierszy w tabeli.
Spróbuj WYJAŚNIĆ, aby zobaczyć kluczową różnicę:
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 |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
Możesz zobaczyć GDZIE lub POZYCJA używa indeksu, ale wiersze są różne.
SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
...HAVING clause can use both column and alias.się ...HAVING clause can use either column or alias.i zmiany ...WHERE clause will be more effectivedo...WHERE clause will be more efficient
Główną różnicą jest to, że WHEREnie można jej użyć na zgrupowanym elemencie (np. SUM(number)), Podczas gdy HAVINGmożna.
Powodem jest WHEREto zrobić przed zgrupowania i HAVINGodbywa się po ugrupowanie jest gotowe.
HAVINGsłuży do filtrowania agregacji w twoim GROUP BY.
Na przykład, aby sprawdzić zduplikowane nazwy:
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
Te 2 będą wyglądały tak samo jak pierwsze, ponieważ oba są używane do powiedzenia o warunku do filtrowania danych. Chociaż w każdym razie możemy użyć słowa „mieć” zamiast „gdzie”, istnieją jednak przypadki, w których nie możemy użyć słowa „gdzie” zamiast „mieć”. Jest tak, ponieważ w zapytaniu select „gdzie” filtruje dane przed „select”, a „mając” filtruje dane po „select”. Tak więc, gdy używamy aliasów, które nie znajdują się w bazie danych, „gdzie” nie może ich zidentyfikować, ale „posiadanie” może.
Np .: niech tabela Uczeń zawiera identyfikator studenta, imię, datę urodzin, adres. Przyjmij, że data urodzin to data.
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.*/
WHEREi HAVING.
GDZIE filtruje przed zgrupowaniem danych, a HAVING filtruje po zgrupowaniu danych. To ważne rozróżnienie; wiersze, które są eliminowane przez klauzulę WHERE , nie zostaną uwzględnione w grupie. Może to zmienić obliczone wartości, co z kolei (= w rezultacie) może wpłynąć na to, które grupy są filtrowane na podstawie użycia tych wartości w klauzuli HAVING .
I kontynuuje
HAVING jest tak podobny do GDZIE, że większość DBMS traktuje je tak samo, jeśli nie określono GROUP BY . Niemniej jednak powinieneś sam to rozróżnić. Używaj opcji HAVING tylko w połączeniu z klauzulami GROUP BY . Użyj GDZIE do standardowego filtrowania na poziomie wiersza.
Fragment: Forta, Ben. „Sams Naucz się SQL w 10 minut (wydanie 5) (Sams Naucz się ...).”.
Posiadanie jest używane tylko z agregacją, ale gdzie z instrukcjami bez agregacji Jeśli masz słowo, które umieść przed agregacją (pogrupuj według)