Я новичок в SQL, и я хотел знать, в чем разница между предложением Where и предложением Have. Для меня это одно и то же, и оба используются для фильтрации записи. Спасибо, что дали мне информацию.
Где против наличия SQL
Ответы (2)
К вашему сведению, помимо запросов SELECT
, вы можете использовать предложение WHERE
с предложением UPDATE и DELETE, но предложение HAVING
можно использовать только с запросом SELECT
. Пример:
update CUSTOMER set CUST_NAME="Johnny" WHERE CUST_ID=1; //This line of code worked
update CUSTOMER set CUST_NAME="Johnny" HAVING CUST_ID=1; //Incorrect Syntax
Предложение WHERE используется для фильтрации строк и применяется к каждой строке, а предложение HAVING используется для фильтрации групп строк в SQL.
В то время как предложения WHERE
и HAVING
можно использовать вместе в запросе SELECT с агрегатной функцией.
SELECT CUST_ID, CUST_NAME, CUST_GENDER
FROM CUSTOMER
WHERE CUST_GENDER='MALE'
GROUP BY CUST_ID
HAVING CUST_ID=8;
В этой ситуации предложение WHERE
сначала будет применяться к отдельным строкам, и только те строки, которые удовлетворяют условию, включаются в создание групп. После создания группы предложение HAVING используется для фильтрации групп на основе указанного условия.
WHERE используется для фильтрации записей до того, как на них воздействует GROUP BY (или в запросах, не имеющих группировки).
HAVING используется для фильтрации строк после того, как с ними подействовал GROUP BY. Вы можете указать столбцы в предложении HAVING только в том случае, если они были сгруппированы или являются частью агрегата (означает, что они передаются какой-либо функции, такой как SUM (столбец), AVG (столбец), COUNT (столбец) и т. д.)
Счета сотрудников, у которых было более одного повышения заработной платы:
--yes
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts'
GROUP BY emp_name
HAVING count(*) > 1
--yes - equivalent if HAVING wasn't a thing
SELECT emp_name
FROM (
--do this first, count the records
SELECT emp_name, COUNT(*) as ct
FROM pay_rise_log
WHERE dept = 'accounts'
GROUP BY emp_name
) a
WHERE a.ct > 1 --and now filter to more than one pay rise
--no, you can't use a count(*) (done during a group by) before the group by is performed
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts' AND count(*) > 1
GROUP BY emp_name
--no
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts'
GROUP BY emp_name
HAVING count(*) > 1 AND gender = 'male' --no, the gender column was not grouped and is not presented inside an aggregate function
--works, but is unusual. gender should be in the where clause
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts'
GROUP BY emp_name, gender
HAVING count(*) > 1 AND gender = 'male'
--works, but gender should be part of the WHERE clause to avoid needlessly counting females
--also has a potential bug if genders alphabetically after 'male' are present
--though it would count people who have been male even if they aren't currently, which may be a bonus?!
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts'
GROUP BY emp_name
HAVING count(*) > 1 AND MAX(gender) = 'male'
MySQL немного утомляет с точки зрения обучения, потому что в некоторых конфигурациях вы можете опустить GROUP BY, и он сделает это неявно за вас, поэтому вы можете не осознавать, что GROUP BY выполняется.
В ответ на ваш комментарий вы можете использовать WHERE перед группой; вы используете его, чтобы выбрать, какие записи вы хотите сгруппировать. Если сотрудников 100 000, а в бухгалтерии только 100, то нет смысла группировать и считать ВСЕХ, только 99% данных выкинуть:
--yes
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts' --pick 100 employees
GROUP BY emp_name
HAVING count(*) > 1 --pick only those with 2 or more pay rises
--no (and potentially wrong too)
SELECT emp_name
FROM pay_rise_log --pick 100,000 employees
GROUP BY emp_name
HAVING count(*) > 1 and MAX(dept) = 'accounts' --pick only accounts staff who had more than 1 pay rise
select x from(select y from t) where a=b
, а неselect y from t group by * having a=b
, но даже в этом случае это плохая практика в контексте обучения - однажды студент перейдет к другим БД. MySQL часто выглядит как VB6 вздрагивает - person Caius Jard   schedule 13.09.2018