2017-02-05 31 views
0

我必须每周从Customer(客户名称,ID)和order(订单ID,订单金额,订单日期)中找到3位消费最高的客户。如果我今天运行查询,它应该显示订单日期存在的所有星期的前3位。如何在SQL中每周对结果进行分区?

我正在考虑在日期(每周)做一个Partition by,但我找不到任何方法来做到这一点?有没有人做过每周分区的结果?

我知道这是不对的,但是这是我有:

Select Top 3 customer_name, id OVER (partition by [week]) 
(
    Select c.customer_name, c.id, o.order_amt, 
    from customer c 
    Join Order o 
     on c.id=o.id 
    group by c.id 
) 
+2

选择一个数据库:'MySQL的= SQL-server'和这个问题的一个答案可能是显著不同,以一个答案另一个。 –

回答

1

根据你的表结构,其中orders.order_idcustomer.id 使用本声明

select 
    * 
from 
(
    select 
     details.* 
     ,dense_rank() over (partition by week_num order by order_amt desc) as rank_num 
    from 
    (
     select 
      c.id as customer_id 
      ,c.name 
      ,sum(o.order_amt) as order_amt 
      ,datepart(WEEK,o.order_date) as week_num  
     from customer c 
     join orders o on c.id=o.order_id 
     group by c.id,c.name,datepart(WEEK,o.order_date) 
    )details 

)dets 
where dets.rank_num<=3 

更新:chan GED声明只使用2台

+0

谢谢!虽然只有2个表,id是客户n订单表中的客户id。但为什么第一个在子查询之外选择密集排名?不能是1查询吗? –

+0

我已更新查询以匹配您的表格结构。 – Lemjur

+0

'Dense_rank()'可以放在第一个子查询中,但是由于行',dense_rank()over(按照datepart(WEEK,o.order_date)按sum(o.order_amt)desc划分的分区) as rank_num' – Lemjur

0

查询应该是这样的

Select customer_name, id, order_amt, [week] 
(
    Select c.customer_name, c.id, o.order_amt, [week], 
      rn = row_number() over (partition by [week] order by o.order_amt desc) 
    from customer c 
    Join Order o 
     on c.id=o.id 
) d 
where rn <= 3 
+0

谢谢!但它会自动将它分成几周,并按“按[周]分区”还是需要添加其他条件或开始日期/订单日期?语法是否正确? –

+0

你为什么试图通过'客户ID'加入2个不同的收藏,这似乎是不同的ID? 'order_id'是否存储'customer_id'信息? – Lemjur

+0

这是更好的选择吗?通过datepart修改分区答案(week,o.order_date)。 选择CUSTOMER_NAME,ID,ORDER_AMT ( 选择c.customer_name,c.id,o.order_amt, ROW_NUMBER()以上(分区由日期部分(周,o.order_date)由o.order_amt递减顺序)为RN 从客户C 通过c.id )d 其中RN <= 3 –

0

这是一个想法,

;WITH CTE 
AS (
    SELECT c.customer_name 
     ,c.id 
     ,o.order_amt 
     ,datepart(wk, datecol) AS Weekcol 
    ) 
    ,CTE1 
AS (
    SELECT c.customer_name 
     ,c.id 
     ,o.order_amt 
     ,ROW_NUMBER() OVER (
      PARTITION BY Weekcol ORDER BY order_amt DESC 
      ) AS rowNUm 
    FROM CTE 
    ) 
SELECT * 
FROM CTE1 
WHERE rowNUm <= 3 
+0

如果2位顾客有相同数量的'orders_amt',该怎么办? 'Dense_rank()'比'Row_num()'好。第二个问题是客户进行的多项操作。他每天可以做超过1次的操作,所以必须在'order_amt'上进行聚合。 – Lemjur

相关问题