2014-01-15 101 views
2

我在MySQL數據庫中有數十萬個產品。每個產品都映射到一個子類別,每個子類別映射到一個類別,並且每個類別映射到一個部門。MySQL結果的排名子集

我需要分別計算其類別/分類/部門內的特定產品的銷售排名,也取兩款產品位列其正上方和兩個產品位列其正下方。下面是一個SQL小提琴獲取所有產品的等級,在子類別:

http://sqlfiddle.com/#!2/d4aad/6

我如何重構查詢與給定的product_id加上兩行的上方和下方只返回產品?例如,對於PRODUCT_ID 8我只想返回這些行:

 
╔══════╦════════════════╦═════════════╦════════════╗ 
║ RANK ║ DESCRIPTION ║ TOTAL_SALES ║ PRODUCT_ID ║ 
╠══════╬════════════════╬═════════════╬════════════╣ 
║ 2 ║ Digital SLR 2 ║  8000 ║   2 ║ 
║ 3 ║ Digital SLR 7 ║  5998 ║   7 ║ 
║ 4 ║ Digital SLR 8 ║  5997 ║   8 ║ 
║ 5 ║ Digital SLR 1 ║  3297 ║   1 ║ 
║ 6 ║ Digital SLR 4 ║  3200 ║   4 ║ 
╚══════╩════════════════╩═════════════╩════════════╝ 

對於PRODUCT_ID 3,返回的數據將是如下:

 
╔══════╦════════════════╦═════════════╦════════════╗ 
║ RANK ║ DESCRIPTION ║ TOTAL_SALES ║ PRODUCT_ID ║ 
╠══════╬════════════════╬═════════════╬════════════╣ 
║ 6 ║ Digital SLR 4 ║  3200 ║   4 ║ 
║ 7 ║ Digital SLR 6 ║  2599 ║   6 ║ 
║ 8 ║ Digital SLR 3 ║  2468 ║   3 ║ 
║ 9 ║ Digital SLR 10 ║  1000 ║   10 ║ 
║ 10 ║ Digital SLR 5 ║  1000 ║   5 ║ 
╚══════╩════════════════╩═════════════╩════════════╝ 

所以PRODUCT_ID是已知的查詢,但是在執行查詢之前排名是未知的。

+1

考慮提供適當的DDL和/或sqlfiddle連同完成所需的結果集 – Strawberry

+0

。我也幾乎完全重寫了這個問題,目的是爲了更容易理解我想要實現的目標。 – user2927684

回答

1

這裏是這樣做的,只是使用MySQL變量的方法 - 所以你不必計算等級兩次。

select t.* 
from (select t.*, 
      @therank := if(product_id = 8, rank, @therank) as therank 
     from (SELECT @rn := @rn + 1 AS rank, 
        description, total_sales, product_id 
      FROM (SELECT ol.product_id, p.description, 
         sum(ol.item_sell_price) AS total_sales 
        FROM products p INNER JOIN 
         order_lines ol 
         ON p.id = ol.product_id 
        WHERE p.subcategory_id = 1 
        GROUP BY ol.product_id 
        ORDER BY total_sales DESC 
       ) t1 cross join 
       (SELECT @rn := 0) const 
      ) t cross join 
      (select @therank := 0) const 
    ) t 
where @therank between rank - 2 and rank + 2 
order by rank 

內部子查詢使用@rn計算排名。下一級通過數據並將@therank設置爲給定產品的等級。最後,這用作最外層的between聲明。

的MySQL確實兌現子查詢。在這種情況下,這可能比重新計算排名要好得多。

+0

+1戈登到我只是檢查一下,看看有沒有人做過這麼難的工作,否則我會回答這個問題,但是你已經救了我工作:) – Bohemian

+0

這很好,非常感謝! – user2927684

0

喜歡的查詢:

SELECT rank, description, total_sales 
FROM (... your query ...) 
ORDER BY rank 
LIMIT 5 OFFSET 3 

會給你記錄爲3到7

+0

感謝您的快速響應! :-)我的問題是我需要計算LIMIT或OFFSET子句中使用的值作爲查詢的一部分,它將基於特定product_id的「rank」值。 – user2927684

+0

對不起,我沒有得到它,你需要動態選擇範圍,以顯示:( –

+0

對不起,我不是太清楚,我包括相當多的不必要的信息。現在所改寫的問題。 – user2927684