Różnica pomiędzy having a where w T-SQL

0

Czy jest jakaś różnica między tymi zapytaniami? Wiem, że HAVING używa się po GROUP BY, a WHERE przed GROUP BY, ale czy czy jest jeszcze jakaś różnica?

SELECT CustomerID, MIN(OrderID) as FirstOrder, MAX(OrderID) as LastOrder
FROM dbo.Orders
WHERE Country IN(SELECT Country FROM dbo.Customers WHERE Country = 'Germany')
GROUP BY CustomerID
ORDER BY CustomerID 
SELECT CustomerID, MIN(OrderID) as FirstOrder, MAX(OrderID) as LastOrder
FROM dbo.Orders
GROUP BY CustomerID
HAVING CustomerID IN(SELECT CustomerID FROM dbo.Customers WHERE Country = 'Germany')
ORDER BY CustomerID 
1

having odnosi się do grup agregacji, where do rekordów

co ciekawe, zobaczysz na planie wykonania ze i tak najpierw wykona się filtrowanie, tak aby zoptymalizować zapytanie przez redukcję rekordów :)

2

Warunki w WHERE działają przed grupowaniem z klauzuli GROUP natomiast HAVING po wykonaniu grupowania.

0

pomijając fakt, że oba są brzydkie to drugie jest bez sensu

0

@abrakadaber: dlaczego uważasz że są brzydkie?

0

Bo to podzapytanie jest bez sensu. Można w samym WHERE napisac country = 'germany'

1

Lepszy przykład to sytuacja gdzie masz jakieś funkcje agregujące i to na ich wartości chcesz mieć warunek, wtedy widać jasno czym się różni where od having. Where odnosi się do jednego rekordu a having do wyniku zapytania (lub do każdej grupy, jeśli mamy grupowanie). Wyobraź sobie że chciałbyś wypisać kategorię produktu, dla której średnia cena artykułu jest większa od 50. Więc warunek chcesz postawić na wyniku funkcji agregującej. Nie da się tutaj użyć "where", bo ono odnosi się do ceny jednego produktu. Trzeba napisać jakieś:

select categories.category_name from categories inner join products on categories.id = products.category_id
group by categories.category_name
having avg(products.price) > 50

W where nie możesz mieć avg(products.price) bo nie miałoby to sensu, a warunek where products.price > 50 odnosiłby się do każdego produktu z osobna.

1 użytkowników online, w tym zalogowanych: 0, gości: 1