2008-11-13 38 views
207

Muszę googlować w niewłaściwy sposób lub mam głupi moment w czasie.Jaka jest różnica między HAVING a WHERE?

Jaka jest różnica między HAVING a WHERE w oświadczeniu SQL SELECT?

EDIT: Mam zaznaczone odpowiedź Stevena za poprawny, ponieważ zawierał kluczy bit informacji na link:

Kiedy GROUP BY nie jest używany, HAVING zachowuje się jak WHERE klauzuli

Sytuacja, w której widziałem numer WHERE, nie miała GROUP BY i jest tam, gdzie zaczęło się moje zamieszanie. Oczywiście, dopóki się tego nie dowiesz, nie możesz podać tego w pytaniu.

Bardzo dziękuję za wszystkie odpowiedzi, które były bardzo pouczające.

+33

Linia, którą zacytujesz, wcale nie jest kluczem. Kluczowy klucz, [jak wskazano wcm] (http://stackoverflow.com/a/287496/877069), polega na tym, że 'HAVING' jest filtrem poagregacyjnym, podczas gdy' WHERE' jest filtrem preagregacji. –

+0

ten link pomógł mi zrozumieć go lepiej niż wszystkie komentarze poniżej, myśl, że ktoś może uzyskać pomoc przez to http://www.codeproject.com/Articles/25258/Where-Vs-Having-Difference-between-having -and-Wher –

Odpowiedz

75

BIORĄC określa warunek wyszukiwania dla grupy lub funkcji Kruszywo stosowane w SELECT.

Source

10

HAVING jest używany, gdy używany jest agregat, taki jak GROUP BY.

SELECT edc_country, COUNT(*) 
FROM Ed_Centers 
GROUP BY edc_country 
HAVING COUNT(*) > 1 
ORDER BY edc_country; 
18

Klauzula HAVING została dodana do SQL, ponieważ słowo kluczowe WHERE nie mogło być używane z funkcjami zagregowanymi.

Sprawdź tę w3schools link więcej informacji

Składnia:

SELECT column_name, aggregate_function(column_name) 
FROM table_name 
WHERE column_name operator value 
GROUP BY column_name 
HAVING aggregate_function(column_name) operator value 

Zapytanie takie jak to:

SELECT column_name, COUNT(column_name) AS column_name_tally 
    FROM table_name 
WHERE column_name < 3 
GROUP 
    BY column_name 
HAVING COUNT(column_name) >= 3; 

... może być zapisane w postaci tabeli pochodzącą (i pomijając HAVING) w następujący sposób:

SELECT column_name, column_name_tally 
    FROM (
     SELECT column_name, COUNT(column_name) AS column_name_tally 
      FROM table_name 
     WHERE column_name < 3 
     GROUP 
      BY column_name 
     ) pointless_range_variable_required_here 
WHERE column_name_tally >= 3; 
+2

Lekko pomijasz punkt: 'HAVING' został dodany, ponieważ tabele pochodne nie zostały dodane do języka i dopóki nie były one SQL kompletnie nieskończone i gdy nieuchronnie" HAVING "stał się zbędny. – onedaywhen

0

I użytkowy mający na ograniczania kwerendę opartą na wynikach funkcji zbiorczej. NA PRZYKŁAD. wybierz * w grupie blahblahblah, COŚ, licząc (COŚ)> 0

0

Od here.

standard SQL wymaga, że ​​posiadanie musi odwoływać się tylko kolumny w grupie klauzuli lub kolumn stosowanych w zagregowanych funkcji

w przeciwieństwie do klauzuli WHERE, która jest stosowana do wierszy bazy

+0

Źródło mówi: "Używanie pozycji kolumn jest przestarzałe, ponieważ składnia została usunięta ze standardu SQL." Niestety, jest to błędne: nic nie jest nigdy usunięte ze Standardu, co ironicznie jest powodem, dla którego nadal mamy "HAVING" dziesięciolecia po tym, jak został "przestarzały" przez wyprowadzone tabele. – onedaywhen

+0

Lekko pedantyczny, ale cytat nie jest poprawny, np. rozważ "SELECT 1 FROM T COVING (*)> = 1;' - nie odwołuje się do kolumn w klauzuli "GROUP BY" (nie ma żadnych) ani kolumn w zagregowanych funkcjach (zapytania nie zawierają żadnych kolumn). – onedaywhen

276

HAVING służy do sprawdzania warunków po przeprowadzeniu agregacji.

WHERE jest używany przed agregacją.

ten kod:

select City, CNT=Count(1) 
From Address 
Where State = 'MA' 
Group By City 

Daje tabelę wszystkich miast w IZ oraz liczbę adresów w każdym mieście.

ten kod:

select City, CNT=Count(1) 
From Address 
Where State = 'MA' 
Group By City 
Having Count(1)>5 

Daje spis miast MA z więcej niż 5 adresów i liczby adresów w każdym mieście.

8

WHERE jest stosowane jako ograniczenie zestawu zwracanego przez SQL; wykorzystuje wbudowane wbudowane funkcje SQL i indeksy, a zatem jest najszybszym sposobem filtrowania zestawów wyników. Zawsze używaj GDZIE, gdy tylko jest to możliwe.

HAVING jest niezbędny w przypadku niektórych filtrów zbiorczych. Filtruje zapytanie PO SQL zostało pobrane, zmontowane i posortowane. Dlatego jest znacznie wolniejszy niż WHERE i należy go unikać, z wyjątkiem sytuacji, które tego wymagają.

SQL Server pozwoli Ci uniknąć używania HAVING nawet gdy WHERE byłby znacznie szybszy. Nie rób tego.

+0

Obsługa tabel wyprowadzonych w języku SQL oznacza, że ​​twoje stwierdzenie "HAVING jest konieczne dla niektórych filtrów zbiorczych" jest fałszywe. – onedaywhen

+1

To dobra uwaga. W ciągu trzech lat, od kiedy napisałem tę odpowiedź, z pewnością migrowałem w kierunku używania tabel pochodnych, w których wcześniej używałem HAVING. Nie zastanawiałem się nad tym, czy HAVING ma jeszcze jakieś przypadki użycia, które mają sens. Nie wiem także, czy wyprowadzona tabela będzie działać lepiej niż HAVING. – davidcl

1

w zapytaniu kruszywa (Każde zapytanie Jeżeli funkcja agregat używany) PREDICATES w klauzuli where oceniano przed zagregowanymi pośredni zestaw wynik uzyskany

Predykaty w HAVING są stosowane w wyniku łącznego ustawić PO jej wygenerowaniu. Dlatego warunki predykatu na wartościach zagregowanych muszą być umieszczone w klauzuli Ma, a nie w klauzuli Where, i dlaczego można używać aliasów zdefiniowanych w klauzuli Select w Klauzuli mającej, ale nie w klauzuli Where.

2

Miałem problem i odkryłem kolejną różnicę między WHERE i HAVING. Nie działa tak samo w przypadku indeksowanych kolumn.

WHERE my_indexed_row = 123 pokaże wiersze i automatycznie wykona "ORDER ZAMÓWIENIA" w innych indeksowanych wierszach.

HAVING my_indexed_row = 123 pokazuje wszystko od najstarszego "wstawionego" wiersza do najnowszego, bez zamawiania.

23

Numer jedna różnica dla mnie: jeśli HAVING został usunięty z języka SQL, życie trwałoby mniej więcej tak jak wcześniej. Oczywiście, zapytania mniejszości będą musiały zostać przepisane przy użyciu wyprowadzonej tabeli, CTE, itd., Ale w rezultacie będą prawdopodobnie łatwiejsze do zrozumienia i utrzymania. Być może kod optymalizacyjny dostawcy musiałby zostać przepisany w celu uwzględnienia tego, ponownie szansa na poprawę w branży.

Teraz rozważ za chwilę usunięcie WHERE z tego języka. Tym razem istniejąca liczba zapytań o istnieniu musiałaby zostać przepisana bez oczywistej alternatywnej konstrukcji. Kodery musiałyby być kreatywne, np. wewnętrzne połączenie z tabelą zawierającą dokładnie jeden wiersz (na przykład DUAL w Oracle) przy użyciu klauzuli ON w celu symulacji wcześniejszej klauzuli WHERE. Takie konstrukcje byłyby wymyślne; byłoby oczywiste, że czegoś brakowało w języku, a sytuacja byłaby gorsza w wyniku.

TL; DR możemy jutro stracić HAVING, a rzeczy nie będą gorsze, być może lepsze, ale tego samego nie można powiedzieć o WHERE.


stąd odpowiedzi, wydaje się, że wiele ludowych nie zdają sobie sprawy, że HAVING klauzula może być używany bez GROUP BY klauzuli. W takim przypadku klauzula HAVING jest stosowana do całego wyrażenia tabelowego i wymaga, aby tylko stałe były wyświetlane w klauzuli SELECT. Zazwyczaj klauzula HAVING będzie zawierała agregaty.

Jest to bardziej przydatne niż się wydaje. Na przykład, rozważmy tę kwerendę, aby sprawdzić, czy kolumna name jest unikalny dla wszystkich wartości w T:

SELECT 1 AS result 
    FROM T 
HAVING COUNT(DISTINCT name) = COUNT(name); 

Są tylko dwa możliwe wyniki: jeżeli klauzula HAVING jest prawdziwe wtedy wynik z być pojedynczy wiersz zawierający wartość 1, w przeciwnym razie wynikiem będzie pusty zbiór.

+0

Czy byłoby to równoważne z "WYBIERZ LICZBĘ (DISTINCT name) = COUNT (name) FROM T"? – MSpreij

+0

@MSpreij Nie wiem, czy to działa, ale nie działa na serwerze SQL 2005, ale pierwszy działa jako – Joe

0

Podczas pracy nad projektem było to również moje pytanie. Jak wspomniano powyżej, sprawdzanie warunku już znalezionego wyniku kwerendy powoduje: . Ale WHERE służy do sprawdzania kondycji podczas wykonywania kwerend.

Pozwolę sobie podać przykład ilustrujący to. Załóżmy, że masz taką tabelę bazy danych.

usertable int {ID użytkownika, data datefield int dailyincome}

Przypuśćmy, że następujące pozycje w tabeli:

1, 2011-05-20, 100

1, 2011-05-21, 50

1, 2011-05-30, 10

2, 2011-05-30, 10

2, 2011-05-20, 20

Teraz chcemy uzyskać userid s i sum(dailyincome) których sum(dailyincome)>100

gdybyśmy Zapis:

SELECT userid, suma (dailyincome) FROM usertable GDZIE suma (dailyincome)> 100 GROUP BY identyfikatora

To będzie błąd.Prawidłowe zapytanie może być:

SELECT identyfikator użytkownika, suma (dailyincome) Z usertable GROUP PRZEZ identyfikatora HAVING sumę (dailyincome)> 100

16

Różnica między nimi w stosunku do grupy Klauzula BY:

  • GDZIE występuje przed GRUPĄ BY; SQL analizuje klauzulę WHERE, zanim zgrupuje rekordy.

  • HAVING pojawia się po GROUP BY; SQL ocenia HAVING po grupowaniu rekordów.

select statement diagram

Odniesienia

+0

. Ponieważ GROUP BY i HAVING są opcjonalne, diagram pokazuje oba przypadki, wystarczy wykonać strzałki. –

+0

Przykładowe zapytanie z mojej odpowiedzi na to pytanie: SELECT 1 AS result From T HAVING ... '- na twoim diagramie nie mogę dostać się do' HAVING' bez przechodzenia przez 'GROUP BY', ale moje całkowicie poprawne i użyteczne zapytanie ma brak "GROUP BY". Drobny punkt: nie masz możliwości uwzględnienia literalnych wartości w klauzuli "SELECT". – onedaywhen

+0

@onedaywhen Od [wiesz] (http://stackoverflow.com/a/9099170/1113772) o niejawnej grupie GROUP BY, dlaczego o tym nie wspomniałeś? Czy wiesz, czy [to zachowanie] (http://stackoverflow.com/questions/15507825/1113772) jest tym, czego się spodziewasz, czy nie? –

1

Klauzula WHERE służy do porównywania wartości w tabeli podstawowej, podczas gdy klauzula HAVING może być używana do filtrowania wyników funkcji agregujących w zestawie wyników zapytania Kliknij here!

0

Możliwe, że temat "gdzie" jest wierszem, podczas gdy temat "posiadanie" to grupa. Czy mam rację?

+3

Przed wysłaniem odpowiedzi należy się upewnić. Może to być mylące dla innych. – pippin1289

22

Różnica między WHERE i HAVING klauzula:

1.WHERE można stosować - SELECT, INSERT i aktualizacji oświadczenia, w którym jako HAVING może tylko używać z instrukcją Select.

2.GDZIE filtry rzędy przed agregacją (grupy), w których jak HAVING filtry grupy po agregacji wykonania.

3. funkcje agregujące nie może być stosowany w WHERE, chyba że jest w kwerendzie sub zawartej w klauzuli HAVING , natomiast łączne funkcje mogą być używane w klauzuli HAVING.

filtrowania Grupy:

WHERE jest używana do filtrowania wierszy przed agregacją, gdzie jako HAVING służy do filtrowania grup po agregacji

Select City, SUM(Salary) as TotalSalary 
from tblEmployee 
Where Gender = 'Male' 
group by City 
Having City = 'London' 

W SQL Server Mamy dużo kruszywa Funkcje. Przykłady

  1. Count()
  2. Sum()
  3. avg()
  4. Min()
  5. Max()
6

WHERE nie działa agregat funkcje
oznacza: nie powinieneś używać tego w ten sposób premia: nazwa tabeli

SELECT name 
FROM bonus 
GROUP BY name 
WHERE sum(salary) > 200 

TUTAJ Zamiast WHERE trzeba użyć HAVING ..

bez użycia klauzuli GROUP BY, HAVING prostu działa jak klauzula WHERE

SELECT name 
FROM bonus 
GROUP BY name 
HAVING sum(salary) > 200 
3

When GROUP BY nie jest używany, klauzule WHERE i HAVING są zasadniczo równoważne.

Jednak, gdy jest używany GROUP BY:

  • Klauzula WHERE służy do filtrowania rekordów z wyniku. Filtrowanie następuje przed utworzeniem grupowania.
  • Klauzula HAVING służy do filtrowania wartości z grupy (tj. Do warunków sprawdzania po wykonaniu agregacji w grupy).

zasobów z Here

1

jeden sposób, aby myśleć o tym jest to, że mając klauzula stanowi dodatkowy filtr do klauzuli WHERE.

A GDZIE Klauzula służy do filtrowania rekordów z wyniku. Filtr występuje przed utworzeniem grupowania. HAVING klauzuli używane do filtrowania wartości z grupy

3

różnica b/w WHERE i HAVING formuły:

Główną różnicą pomiędzy WHERE i HAVING klauzuli jest WHERE służy do operacji wierszy i HAVING jest używany do operacji na kolumnach.

Dlaczego potrzebujemy klauzuli HAVING?

Jak wiemy, funkcje agregujące mogą być wykonywane tylko w kolumnach, więc nie możemy używać funkcji agregujących w klauzuli WHERE. Dlatego używamy funkcji agregujących w klauzuli HAVING.

0

Klauzula WHERE jest oceniana przed zgrupowaniem wierszy, a zatem jest oceniana dla każdego wiersza.

Klauzula jest oceniana po zgrupowaniu wierszy, a zatem jest obliczana dla grupy.