mysql - 为什么这个 MySQL 查询会产生错误的行号?

标签 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 |
+---------+------------+------------+------------+---------------+

我做错了什么?

编辑:

Michael 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;

最佳答案

要使行递增,只需将 @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

关于mysql - 为什么这个 MySQL 查询会产生错误的行号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14664516/

相关文章:

mysql - 如何在 Windows 上的 AppServ 上启用 PDO?

php - mysql 使用 IF NOT IN 关键字或替代方法选择所有其他数据

php - 解释所有mysql select查询 "Kohana Framework 3"模型的方法

mysql - varchar 的最小值?

mysql - 通过Nodejs向Mysql插入数据

sql - 在mysql中执行计算

python - Django - 过滤 prefetch_related 查询集

mysql - 在 MySql 中插入 500 条简单的行,耗时超过 40 秒

php - 无法通过post方法携带表单值

PHP MySQL 插入文件,使用带有 OR 运算符的 IF 语句验证表单