1

我遇到了这样一个问题,即退回客户共同购买的前 N ​​对产品。假设我有以下查询:

SELECT c.CustomerKey, ProductAlternateKey
FROM 
    [AdventureWorksDW2008R2].[dbo].[FactInternetSales] FIS JOIN
    dbo.DimCustomer C ON C.CustomerKey = FIS.CustomerKey JOIN
    dbo.DimProduct P ON P.ProductKey = FIS.ProductKey

GROUP BY 
    C.CustomerKey, P.ProductAlternateKey

它返回以下结果:

CustomerKey  | ProductAlternateKey| 
-------------+-----------+
0001         | A                  |
0001         | B                  |
0002         | A                  | 
0002         | B                  |
0002         | C                  |
0003         | B                  |
0003         | C                  |
0004         | A                  |
0004         | B                  |
0005         | A                  |
0005         | C                  |

从这个查询中,我想找到客户购买的前 2 对产品,所以在我的示例中 -> (A,B) 3 次出现和 (B,C) -> 2 次出现

4

2 回答 2

1

使用 RANK 或 DENSERANK 函数。MSDN 关于 Rank 功能:http: //msdn.microsoft.com/en-us/library/ms176102.aspx

自提取 SQL 的示例用法:

declare @Person Table ( personID int identity, person varchar(8));

insert into @Person values ('Brett'),('Sean'),('Chad'),('Michael'),('Ray'),('Erik'),('Queyn');

declare @Orders table ( OrderID int identity, PersonID int, Desciption varchar(32), Amount int);

insert into @Orders values (1, 'Shirt', 20),(1, 'Shoes', 50),(2, 'Shirt', 22),(2, 'Shoes', 20),(3, 'Shirt', 20),(3, 'Shoes', 50),(3, 'Hat', 20),(4, 'Shirt', 20),(5, 'Shirt', 20),(5, 'Pants', 30),
(6, 'Shirt', 20),(6, 'RunningShoes', 70),(7, 'Shirt', 22),(7, 'Shoes', 40),(7, 'Coat', 80);

with a as 
    (
    Select
        person
    ,   o.Desciption
    ,   o.Amount
    ,   rank() over(partition by p.personId order by Amount) as Ranking
    ,   Dense_rank() over(partition by p.personId order by Amount) as DenseRanking
    from @Person p
        join @Orders o on p.personID = o.PersonID
    )
select *
from a 
where Ranking <= 2  -- determine top 2, 3, etc.... whatever you want.
order by person, amount
于 2013-03-25T16:44:50.773 回答
1

测试一下:

declare @Orders table ( OrderID int identity, PersonID int,  Description varchar(32), ProductId int, Amount int);

insert into @Orders values (1, 'Shirt', 1, 20),(1, 'Shoes', 2, 50),(2, 'Shirt', 1, 22),(2, 'Shoes', 2, 20),(3, 'Shirt', 1, 20),(3, 'Shoes', 2, 50),(3, 'Hat',   3, 20),(4, 'Shirt', 1, 20),(5, 'Shirt', 1, 20),(5, 'Pants', 4, 30),(6, 'Shirt', 1, 20),(6, 'RunningShoes', 5, 70),(6, 'Hat', 3, 20),(7, 'Shirt', 1, 22),(7, 'Shoes', 2, 40),(7, 'Coat', 6, 80);

select
     top 2       
     I.Description,
     M.Description
from @Orders as I
inner join @Orders as C on C.ProductId = I.ProductId   and C.PersonId <> I.PersonId
inner join @Orders as M on C.PersonId = M.PersonId and C.ProductId <> M.ProductId
where 
    I.productid = 3
    and I.ProductId<>M.ProductId
group by 
    I.Description
    ,M.Description
order
    by count(2) desc
于 2013-03-26T02:40:27.880 回答