Вопрос интервью о SQL group by и наличии

#sql #group-by #having #having-clause

#sql #group-by #наличие #having-предложение

Вопрос:

Эта проблема связана со следующим

https://www.programmerinterview.com/index.php/database-sql/advanced-sql-interview-questions-and-answers/

Предположим, у нас есть две таблицы:

 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 значения, он ничего не знает о бизнес-логике, стоящей за столбцом, который вы просите его посчитать.