对于家庭作业,我试图在2012年1月使用AdventureWorks2014找到每个销售人员的畅销产品。
这是我到目前为止所做的:
SELECT
Person.Person.LastName, Person.Person.FirstName,
Person.Person.MiddleName,
Employee_1.JobTitle,
Sales.SalesPerson.SalesQuota, Sales.SalesOrderHeader.OrderDate,
Production.Product.Name,
SUM(distinct OrderQty) AS Expr2
FROM
Sales.SalesOrderDetail
INNER JOIN
Production.Product ON Sales.SalesOrderDetail.ProductID = Production.Product.ProductID
INNER JOIN
Sales.SalesOrderHeader ON Sales.SalesOrderDetail.SalesOrderID = Sales.SalesOrderHeader.SalesOrderID
AND Sales.SalesOrderDetail.SalesOrderID = Sales.SalesOrderHeader.SalesOrderID
AND Sales.SalesOrderDetail.SalesOrderID = Sales.SalesOrderHeader.SalesOrderID
INNER JOIN
Sales.SalesPerson ON Sales.SalesOrderHeader.SalesPersonID = Sales.SalesPerson.BusinessEntityID
AND Sales.SalesOrderHeader.SalesPersonID = Sales.SalesPerson.BusinessEntityID
AND Sales.SalesOrderHeader.SalesPersonID = Sales.SalesPerson.BusinessEntityID
AND Sales.SalesOrderHeader.SalesPersonID = Sales.SalesPerson.BusinessEntityID
INNER JOIN
HumanResources.Employee AS Employee_1
INNER JOIN
Person.Person ON Employee_1.BusinessEntityID = Person.Person.BusinessEntityID
ON Sales.SalesPerson.BusinessEntityID = Employee_1.BusinessEntityID
AND Sales.SalesPerson.BusinessEntityID = Employee_1.BusinessEntityID
WHERE
(Sales.SalesOrderHeader.OrderDate BETWEEN '2012-01-01' AND '2012-01-31')
GROUP BY
Person.Person.LastName, Person.Person.FirstName, Person.Person.MiddleName,
Employee_1.JobTitle,
Sales.SalesPerson.SalesQuota, Sales.SalesOrderHeader.OrderDate,
Production.Product.Name
ORDER BY
Person.Person.LastName, Production.Product.Name
我无法弄清楚如何为每个产品添加所有orderqty。在前两行结果中,我有同一个人销售的相同产品。我想将它们加在一起,然后找到每个销售人员的前5个产品?
有人可以帮忙吗?
答案 0 :(得分:0)
我的最初目标是将聚合数据集缩减到最少的所需数量表以执行聚合(SalesOrderHeader, SalesOrderDetail
)并将其与附加信息(例如Person, Employee
)连接到表中。
我在聚合子查询中包含了Product
表,但是可以在聚合查询之后完成并加入到ProductId(将其添加到group by
和select
之后)
有很多方法可以做到这一点,这里有一些:
交叉apply 版本:
select
p.LastName
, p.FirstName
, p.MiddleName
, e.JobTitle
, s.SalesQuota
, s.OrderDate
, s.ProductName
, s.TotalQty
from Person.Person as p on
inner join HumanResources.Employee as e on e.BusinessEntityID = p.BusinessEntityID
cross apply (
select top 5 /* 5 rows */
soh.SalesPersonID
, p.ProductName
, TotalQty = sum(OrderQty)
from Sales.SalesOrderHeader as soh
inner join Sales.SalesOrderDetail sod on soh.SalesOrderID = sod.SalesOrderID
inner join Production.Product as pr on sod.ProductID = pr.ProductID
where soh.OrderDate between '2012-01-01' and '2012-01-31'
and s.SalesPersonID = p.BusinessEntityID /* per person */
group by soh.SalesPersonID, p.ProductName
order by sum(OrderQty) desc
/* ordered by sum(OrderQty) descending */
) s
top with ties 版本:
select top 5 with ties
p.LastName
, p.FirstName
, p.MiddleName
, e.JobTitle
, s.SalesQuota
, s.OrderDate
, s.ProductName
, s.TotalQty
from Person.Person as p on
inner join HumanResources.Employee as e on e.BusinessEntityID = p.BusinessEntityID
inner join (
select
soh.SalesPersonID
, p.ProductName
, TotalQty = sum(OrderQty)
from Sales.SalesOrderHeader as soh
inner join Sales.SalesOrderDetail sod on soh.SalesOrderID = sod.SalesOrderID
inner join Production.Product as pr on sod.ProductID = pr.ProductID
where soh.OrderDate between '2012-01-01' and '2012-01-31'
group by soh.SalesPersonID, p.ProductName
) on s.SalesPersonID = p.BusinessEntityID
order by row_number() over (partition by p.BusinessEntityID order by s.TotalQty desc)
/* returns all rows where row_number() over() evaluates to 1,2,3,4 ,or 5 */
使用 common table expression 版
with top5 as (
select
p.LastName
, p.FirstName
, p.MiddleName
, e.JobTitle
, s.SalesQuota
, s.OrderDate
, s.ProductName
, s.TotalQty
, rn=row_number() over (partition by p.BusinessEntityID order by s.TotalQty desc)
from Person.Person as p on
inner join HumanResources.Employee as e on e.BusinessEntityID = p.BusinessEntityID
inner join (
select
soh.SalesPersonID
, p.ProductName
, TotalQty = sum(OrderQty)
from Sales.SalesOrderHeader as soh
inner join Sales.SalesOrderDetail sod on soh.SalesOrderID = sod.SalesOrderID
inner join Production.Product as pr on sod.ProductID = pr.ProductID
where soh.OrderDate between '2012-01-01' and '2012-01-31'
group by soh.SalesPersonID, p.ProductName
) on s.SalesPersonID = p.BusinessEntityID
)
select
LastName
, FirstName
, MiddleName
, JobTitle
, SalesQuota
, OrderDate
, ProductName
, TotalQty
from top5
where rn < 6