#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, я обновил ответ, чтобы включить все столбцы