2017-02-05 67 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

相關問題