#sql #group-by #having #having-clause
#sql #group-by #наличие #having-предложение
Вопрос:
Эта проблема связана со следующим
Предположим, у нас есть две таблицы:
Salesperson
ID Name Age Salary
Orders
Number order_date cust_id salesperson_id Amount
Вопрос заключается в следующем:
Мы хотим получить имена всех продавцов, у которых более 1 заказа, из приведенных выше таблиц. Можно предположить, что у каждого продавца есть только один идентификатор. Я бы, вероятно, также предположил, что все имена различны.
Мой ответ был таким.
select Name from
salesperson S inner join Orders O
on S.ID=O.salesperson_id
group by Name
having count(number) >=2
Однако данный ответ следующий:
SELECT Name
FROM Orders inner join Salesperson
On Orders.salesperson_id = Salesperson.ID
GROUP BY salesperson_id, NAME
Having count(salesperson_id) > 1
Если name и salesperson_id совпадают один к одному, есть ли какая-либо причина, по которой мы должны добавить salesperson_id в инструкцию group by здесь? Кроме того, если отношение name и salesperson_id просто один к одному, не будет ли количество (salesperson_id) всегда равняться 1, если мы группируем по salesperson_id, name?
Я был немного смущен этим, и мне было интересно, сталкивался ли кто-нибудь с этой проблемой раньше и находил ли это странным.
Комментарии:
1. Оба запроса выдают одинаковый результат. Единственная причина поместить
salesperson_id
вgroup by
предложение — это если вы хотите, чтобы оно тоже было вselect
.2. @rad Я не согласен.
salesperson_id
скорее всего, добавляется вGROUP BY
, чтобы учесть вероятность того, что у двух продавцов случайно окажется одно и то же имя. Я3. @Tim Beigeleisen OP предполагает, что все имена также являются уникальными. Следовательно, между двумя
group by
предложениями нет разницы.4. Вы можете предположить, что у каждого продавца есть только один идентификатор , но не имя, как сказал Тим, комбинация имени и идентификатора делает их уникальными, поэтому нам нужны оба в предложении group by.
5. Но как насчет count(salesperson_id)? Разве это не всегда было бы 1?
Ответ №1:
Как ваше решение, так и принятое функционально идентичны, за исключением GROUP BY
предложения.
Вероятная причина, по которой принятое решение объединяет оба по Name
и salesperson_id
, заключается в том, что может случиться так, что у двух или более продавцов совпадут имена. Если это произойдет, ваш запрос выдаст только одно имя, но с совокупными результатами от более чем одного продавца. Но комбинация salesperson_id
и Name
всегда должна быть уникальной.
Кроме этого, я на самом деле предпочитаю вашу версию, и я бы начал присоединяться из salesperson
таблицы out к Orders
таблице.
Комментарии:
1. Моей самой большой проблемой был опубликованный ответ: что, если пара (NAME, salesperson_id) имеет более 1 номеров заказа? Если мы применим group by Name, salesperson_id и отфильтруем по количеству (salesperson_id) > 1, то, я думаю, мы упустим эти случаи. Вот почему я подумал, что мой ответ был правильным, а не то, что было опубликовано.
2. @user98235 Я думаю, вы можете быть сбиты с толку тем, как
HAVING
работает, и в вашей логике нет ничего плохого.COUNT
Функция считает любое неNULL
значение равным 1. Итак, ваша логика просто говорит, дайте мне всех продавцов с 2 или более заказами; это правильно.3. Я думаю о следующих случаях: давайте предположим, что у нас есть две строки (Jim, 1, 10), (Jim, 1, 12), которые представляют собой просто триплет name, salespersonid, ordernumber. У Джима явно больше 1 заказа, но если мы выберем name, salespersonid из табличной группы по имени, salespersonid, имеющий count (salespersonid) > 1, тогда не будет ли count (salespersonid) = 1 для Jim? Однако, если мы сделаем count(odernumber)> 1, то будет выбран Jim.
4. Нет, это присвоило бы значение 2 Джиму. Опять же,
COUNT
просто считает неNULL
значения, он ничего не знает о бизнес-логике, стоящей за столбцом, который вы просите его посчитать.