Odpowiedzi:
Dlaczego musisz umieścić kolumny, które sam tworzysz (na przykład „wybierz 1 jako liczbę”) po HAVINGU, a nie GDZIE w MySQL?
WHERE
jest stosowany przed GROUP BY
, HAVING
jest 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 MySQL
pozwala na przedstawieniu SELECT
aliasy w poziomie GROUP BY
, ORDER BY
a 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 WHERE
klauzuli 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 effective
do...WHERE clause will be more efficient
Główną różnicą jest to, że WHERE
nie można jej użyć na zgrupowanym elemencie (np. SUM(number)
), Podczas gdy HAVING
można.
Powodem jest WHERE
to zrobić przed zgrupowania i HAVING
odbywa się po ugrupowanie jest gotowe.
HAVING
sł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.*/
WHERE
i 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)