2

我有两张表如下 -

销售记录:

    Date    |   Customer   |    ItemSold 
-----------------------------------------
11/01/2013  |     Alex     |     Pen
12/01/2013  |     Rony     |     Paper
13/01/2013  |     Alex     |     Eraser
14/01/2013  |     Marty    |     Eraser
15/01/2013  |     Alex     |     Pen
16/01/2013  |     Rob      |     Paper
17/01/2013  |     Alex     |     Pencil
18/01/2013  |     Alex     |     Pen
19/01/2013  |     Ned      |     Pen
20/01/2013  |     Alex     |     Paper
21/01/2013  |     Alex     |     Pencil
22/01/2013  |     Ned      |     Pen
23/01/2013  |     Alex     |     Eraser
24/01/2013  |     Alex     |     Pen
25/01/2013  |     Alex     |     Pen
26/01/2013  |     Alex     |     Paper
27/01/2013  |     Ned      |     Paper
28/01/2013  |     Alex     |     Pen
29/01/2013  |     Alex     |     Eraser
30/01/2013  |     Alex     |     Pen
31/01/2013  |     Rony     |     Pencil
01/02/2013  |     Alex     |     Eraser
02/02/2013  |     Ned      |     Paper
03/02/2013  |     Alex     |     Pen

优先:

ItemName    |    Priority
--------------------------
Pen         |       1
Paper       |       2
Pencil      |       3
Eraser      |       4

我想获得一份清单,以了解哪些客户可能会购买以下内容 -

Name   |   Item
----------------
Alex   |   Pen
Rob    |   Paper
Ned    |   Pen
Marty  |   Eraser
Rony   |   Paper

如果与项目有联系,则应选择优先级最高的项目。Ned 每次都买了笔和纸两次,但应该选择笔,因为它比纸更优先。

这将是什么 sql 查询?

4

3 回答 3

1

SQL小提琴

select distinct on (customer)
    customer, itemsold, total
from
    (
        select customer, itemsold, count(*) total
        from sales
        group by customer, itemsold
    ) s
    inner join priority on itemsold = itemname
order by customer, total desc, priority
于 2013-09-07T13:08:14.950 回答
1

从统计上讲,您正在寻找的术语是mode. 这是使用窗口/分析函数计算它的一种方法:

select customer, ItemSold
from (select customer, ItemSold, count(*),
             row_number() over (partition by customer order by count(*) desc, p.priority
                               ) as seqnum
      from sales s left outer join
           priority p
           on s.ItemSold = p.ItemName
      group by customer, ItemSold
     ) ci
where seqnum = 1;
于 2013-09-07T12:45:50.550 回答
0

我认为这将是最快的方法。请注意,我在 中使用了优先级order by,但没有在中使用它- 如果您在表中具有togroup by的功能依赖关系,PostgreSQL 允许这样做:itemnamepriorityPriority

select distinct on (s.customer)
    s.customer, p.itemname, count(*) as total
from sales as s
    inner join priority as p on p.itemname = s.itemsold
group by s.customer, p.itemname
order by s.customer, total desc, p.priority

如果不可能,您可以使用以下查询:

select distinct on (s.customer)
    s.customer, s.itemsold, count(*) as total
from sales as s
    inner join priority as p on p.itemname = s.itemsold
group by s.customer, s.itemsold, p.priority
order by s.customer, total desc, p.priority;

sql fiddle demo

于 2013-09-07T19:25:56.250 回答