2017-01-22 7 views
0

Для задания домашней работы я пытаюсь найти товары для топлекса каждым продавцом в январе 2012 года с помощью AdventureWorks2014.Использование SQL Server, как я могу найти продукты для точечного маркетинга у каждого продавца в 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

Вы должны использовать RANK() и PARTITION BY. Существует множество примеров, таких как www.mikesknowledgebase.com/pages/SQLServer/Rank.htm –

+0

@MikeGledhill [sql server 'rank()' versus 'row_number()'] (http://stackoverflow.com/ Вопросы/7747327/sql-rank-versus-row-number) - Я думаю, вы имели в виду 'row_number()' – SqlZim

ответ

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 с row_number() версии:

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