2013-02-02 83 views
1

給出下面的查詢形式的爲什麼這個MySQL查詢產生錯誤的行號?

SET @num :=0, @current_shop_id := NULL, @current_product_id := NULL; 

SELECT * FROM (

SELECT products.shop_id, products.product_id, @num := IF(@current_shop_id=shops.shop_id, IF(@current_product_id=products.product_id,@num,@num+1),0) AS row_number, @current_shop_id := shops.shop_id AS shop_dummy, @current_product_id := products.product_id AS product_dummy 

    FROM 
    favorites fav1 INNER JOIN 
    products ON 
    fav1.product_id=products.product_id AND 
    fav1.current=1 AND 
    fav1.closeted=1 AND 
    fav1.user_id=30 INNER JOIN 

    shops ON 
    shops.shop_id = products.shop_id 

    ORDER BY shops.shop ASC, products.product_id DESC 

) AS rowed_results WHERE rowed_results.row_number>=0 AND rowed_results.row_number<(20) AND shop_id=130 

我期待ROW_NUMBER值

+---------+------------+------------+------------+---------------+ 
| shop_id | product_id | row_number | shop_dummy | product_dummy | 
+---------+------------+------------+------------+---------------+ 
|  130 | 1153746 |   0 |  130 |  1153746 | 
|  130 | 1153736 |   1 |  130 |  1153736 | 
|  130 | 1139944 |   2 |  130 |  1139944 | 
|  130 | 1098296 |   3 |  130 |  1098296 | 
|  130 | 1017455 |   4 |  130 |  1017455 | 
|  130 |  551953 |   5 |  130 |  551953 | 
|  130 |  551914 |   6 |  130 |  551914 | 
+---------+------------+------------+------------+---------------+ 

(即,與給定shop_id值相關聯的所有獨特的product_id值獲得一個唯一的行號,從0開始)。相反,我越來越

+---------+------------+------------+------------+---------------+ 
| shop_id | product_id | row_number | shop_dummy | product_dummy | 
+---------+------------+------------+------------+---------------+ 
|  130 | 1153746 |   1 |  130 |  1153746 | 
|  130 | 1153736 |   0 |  130 |  1153736 | 
|  130 | 1139944 |   0 |  130 |  1139944 | 
|  130 | 1098296 |   0 |  130 |  1098296 | 
|  130 | 1017455 |   0 |  130 |  1017455 | 
|  130 |  551953 |   1 |  130 |  551953 | 
|  130 |  551914 |   0 |  130 |  551914 | 
+---------+------------+------------+------------+---------------+ 

我做錯了什麼?

編輯:

邁克爾Berkowski的解決方案(使用三個查詢,一個用於檢索數據,一個用於添加行號,一個由行限制)的作品(語法略有變化):

SET @num :=0, @current_shop_id := NULL, @current_product_id := NULL; 

#limit by row 

SELECT * FROM (

    #add row 

    SELECT limit_query.*, @num := IF(@current_shop_id=shop_id, IF(@current_product_id=product_id,@num,@num+1),0) AS row_number, @current_shop_id := shop_id AS shop_dummy, @current_product_id := product_id AS product_dummy FROM (

     #retrieve data 

     SELECT row_query.* FROM (

      SELECT products.shop_id, products.product_id 

      FROM 
      favorites fav1 INNER JOIN 
      products ON 
      fav1.product_id=products.product_id AND 
      fav1.current=1 AND 
      fav1.closeted=1 AND 
      fav1.user_id=30 INNER JOIN 

      shops ON 
      shops.shop_id = products.shop_id 

     ) AS row_query ORDER BY shop_id ASC, product_id DESC 

    ) AS limit_query 

) AS rowed_results WHERE rowed_results.row_number>=0 AND rowed_results.row_number<(20) AND shop_id=130; 

純作爲教育興趣的問題,我想知道爲什麼不可能同時添加行號和行號限制,如下面的(非功能性)示例

SET @num :=0, @current_shop_id := NULL, @current_product_id := NULL; 

#limit by row 

SELECT rowed_results.*, @num := IF(@current_shop_id=shop_id, IF(@current_product_id=product_id,@num,@num+1),0) AS row_number, @current_shop_id := shop_id AS shop_dummy, @current_product_id := product_id AS product_dummy FROM (

    #retrieve data 

    SELECT row_query.* FROM (

     SELECT products.shop_id, products.product_id 

     FROM 
     favorites fav1 INNER JOIN 
     products ON 
     fav1.product_id=products.product_id AND 
     fav1.current=1 AND 
     fav1.closeted=1 AND 
     fav1.user_id=30 INNER JOIN 

     shops ON 
     shops.shop_id = products.shop_id 

    ) AS row_query ORDER BY shop_id ASC, product_id DESC 

) AS rowed_results WHERE row_number>=0 AND row_number<(20) AND shop_id=130; 
+0

我猜你在選擇中使用'@num:='這一事實並沒有幫助 – cheesemacfly

+0

爲什麼你需要這個'IF'來計算這個'ro_number'?從'row_number'值你期待'@num:= @num + 1'會給你你正在尋找的確切值。 –

+0

@MahmoudGamal你是對的,舉個例子。這是一個更復雜的查詢的簡化版本,其中多行可能具有相同的product_id值,需要條件(因爲只有具有唯一product_id值的行應具有唯一的row_number值)。 – jela

回答

1

要使行增加,它應該與將@num計算移動到外部查詢中一樣簡單。在這種情況下,@current_product_id不應該需要,因爲@num可以直接增加。

SET @num :=0, @current_shop_id := NULL, @current_product_id := NULL; 

SELECT 
    *, 
    /* Perform the row increment in the outer query so it acts on the final rowset */ 
    @num := @num+1 AS row_number 
FROM (
    SELECT products.shop_id, products.product_id, @current_shop_id := shops.shop_id AS shop_dummy, @current_product_id := products.product_id AS product_dummy 

    FROM 
    favorites fav1 INNER JOIN 
    products ON 
    fav1.product_id=products.product_id AND 
    fav1.current=1 AND 
    fav1.closeted=1 AND 
    fav1.user_id=30 INNER JOIN 

    shops ON 
    shops.shop_id = products.shop_id 

    ORDER BY shops.shop ASC, products.product_id DESC 

) AS rowed_results 
WHERE 
    rowed_results.row_number>=0 
    AND rowed_results.row_number<(20) 
    AND shop_id=130 
+0

我按照你的建議,似乎已經通過移動@num計算得到它的工作,然後通過第三個查詢限制行號。我不能使用第三個查詢來限制行號(見查詢添加到主要問題),我很好奇爲什麼可能會這樣。我的'product_id'值實際上並不是唯一的,所以我認爲有必要保留'@ current_product_id'以確定是否增加'row_number'值(因爲具有相同'product_id'值的不同行應該具有相同的' row_number'值) – jela

+0

@jela'row_number'在應用'WHERE'子句時還不知道,我應該捕獲它。 –

0

您的邏輯檢查商店ID和產品ID。如果它們相同,則計數器遞增,否則重置爲零。雖然您的結果集具有所有相同的商店ID,但它具有不同的產品ID。