mysql删除“n”行之间的记录

hkmswyz6  于 2021-06-21  发布在  Mysql
关注(0)|答案(5)|浏览(261)

我试着在第二行和第五行之间选择记录。我的id不是按顺序排列的,所以我试图检索 row_number 这种方式:

SELECT  @curRow := @curRow + 1 AS row_number
FROM    product_image p
JOIN    (SELECT @curRow := 0) r
WHERE   row_number BETWEEN 2 AND 5

我的table有点像:

id  name 
23  A
42  B
98  C
102 D
109 E

我得到的是 row_number column doesn't exist 而且它真的不存在。但是如何检索2和5之间的记录(第3和第4)?我也发了类似的帖子,但不太理解这个问题。提前谢谢!

hwamh0ep

hwamh0ep1#

检查这个-http://sqlfiddle.com/#!9/c462d/5号机组

select * from 
    (
    SELECT  @curRow := @curRow + 1 AS row_number,p.*
    FROM    product_image p
    JOIN    (SELECT @curRow := 0) r)
    a 
    WHERE   a. row_number BETWEEN 2 AND 5
mftmpeh8

mftmpeh82#

因为您实际上不需要选择行号,所以不需要依赖像 @curRow := @curRow + 1 . 只是使用 LIMIT 以及 OFFSET . 从中选择行 25 你只需要

select id
from product_image
order by name, id
limit 4
offset 1

请注意,您需要一个定义良好的 ORDER BY 条款。否则,结果可能取决于引擎使用的索引。
要删除这些行,请使用 DELETE .. JOIN 声明

delete product_image
from product_image
join (
  select id
  from product_image
  order by name, id
  limit 4
  offset 1
)x using(id)

演示:http://sqlfiddle.com/#!9/66fa4/1号
别耍花招。没有复杂的查询。

vuktfyat

vuktfyat3#

要向查询中添加合成行号,需要一个子查询。就像这样。

SELECT id FROM (
          SELECT    p.*, @curRow := @curRow + 1 AS row_number
            FROM    product_image p
            JOIN    (SELECT @curRow := 0) r
         ) q
 WHERE   row_number BETWEEN 2 AND 5

然后,如果愿意,可以使用结果来驱动删除操作。

DELETE FROM product_image
    WHERE id IN (
    SELECT id FROM (
              SELECT    p.*, @curRow := @curRow + 1 AS row_number
                FROM    product_image p
                JOIN    (SELECT @curRow := 0) r
             ) q
     WHERE   row_number BETWEEN 2 AND 5
    )

但这是一件非常糟糕的事情。为什么?您依赖于内部查询结果集中的特定顺序。sql结果集中的行是,没有任何 ORDER BY 子句,以不可预知的顺序返回。服务器优化器利用了这一点。不可预测就像随机的,但更糟。random意味着每次运行查询时顺序都不太可能相同。这里的random很好,因为你会在测试中发现你的问题。另一方面,不可预测意味着在不可预测之前,顺序保持不变。如果你不确定为什么那样不好,查一下墨菲定律。

zazmityj

zazmityj4#

查询失败的原因是不能在查询中使用列别名 WHERE 条款。但是,您可以在 GROUP BY 以及 HAVING :

SELECT  *, @curRow := @curRow + 1 AS row_number
FROM    product_image p
JOIN    (SELECT @curRow := 0) r
GROUP BY row_number
HAVING row_number between 2 and 5
vnjpjtjt

vnjpjtjt5#

你可以做一个 DELETEJOIN :

DELETE p
FROM product_image p
INNER JOIN (    
   SELECT  id,  @curRow := @curRow + 1 AS row_number
   FROM    product_image p
   CROSS JOIN    (SELECT @curRow := 0) r
   ORDER BY id
) AS t ON p.id = t.id
WHERE t.row_number IN (2,3)

派生表 t 是使用您的查询创建的。您可以加入此表,以便识别所需的任何记录并将其删除。
此处演示

相关问题