SQL-запрос для получения общего количества заказов для каждого пользователя

#sql-server #tsql

#sql-сервер #tsql

Вопрос:

Напишите команду SQL, которая извлекает фамилии и отчества всех клиентов и порядковые номера размещенных ими заказов…

ТАБЛИЦА CustDetails: http://prntscr.com/msicdp ТАБЛИЦА OrderDetails: http://prntscr.com/msichp

Я пытаюсь отобразить список всех пользователей из CustDetails (таблица) с дополнительным столбцом «TotalOrders», который подсчитывает, сколько заказов у каждого пользователя из OrderDetails (таблица) с помощью COUNT (*), но, похоже, я понятия не имею, что я делаю.

Я пробовал ЛЕВОЕ СОЕДИНЕНИЕ в паре с COUNT(*) AS [Total Orders] , и я получаю всевозможные ошибки, что бы я ни пробовал

 SELECT DISTINCT CustDetails.*, OrderDetails.CustRef,COUNT(*) AS [Order_number]
FROM CustDetails
LEFT JOIN OrderDetails ON CustDetails.CustRef = OrderDetails.CustRef
GROUP BY CustDetails.FName
--SELECT CustDetails.CustRef, count(*) AS NUM
--  FROM CustDetails GROUP BY CustRef
  

Комментарии:

1. Добро пожаловать в StackOverflow! Пожалуйста, процитируйте / опишите результаты, которые заставляют вас сомневаться в вашей компетентности. (Обратите внимание, что указанная задача запрашивает не количество заказов , а the order numbers .)

2. @greybeard о, я понимаю… возможно, им просто нужен номер order_ref для каждого пользователя… что, если у 1 пользователя более 1 заказа… я в замешательстве…

Ответ №1:

Вы не можете поставить * с GROUP BY . Если вы используете GROUP BY , в вашем GROUP BY предложении должны присутствовать все неагрегированные столбцы.

Вам нужно написать свой запрос следующим образом.

 select c.CustRef,
       c.LName,
       c.Fname,
       sum(case when od.CustRef is null then 0 else 1 end) TotalOrders
from CustDetails c
left join OrderDetails od on od.CustRef =c.CustRef
group by c.CustRef ,c.LName, C.Fname
  

В случае, если вам нужны все столбцы, вы можете попробовать следующее без GROUP BY .

 select *,
       (select count(*) from OrderDetails od where  od.CustRef =c.CustRef) TotalOrders
from CustDetails c
  

Другой способ сделать это с помощью PARTITION BY

 select * from
(
select c.*,
        sum(case when od.CustRef is null then 0 else 1 end) over(partition by c.CustRef) as TotalOrders,
        row_number() over (partition by c.CustRef order by (select 1)) rn
from CustDetails c
left join OrderDetails od on od.CustRef =c.CustRef
) t
where rn=1
  

Комментарии:

1. спасибо, это все, что мне было нужно… у меня вопрос, почему вы использовали coalesce() ? я попробовал без этого, и это работает так же… хм? также почему мы должны включать все столбцы в group by ? Заранее благодарю @PSK

2. изначально coalesce использовался для изменения null на 0, но в вашем случае вам не нужен coalesce.

3. @Bournee, я обновил ответ, чтобы включить все столбцы