我有一个带有这4列的表格biblek2:
id (autoincrement)
catid(int)
introtext(varchar)
ordering(int)
表biblek2_items
╔════╦═══════╦═══════════╦══════════╗
║ ID ║ catid ║ introtext ║ ordering ║
╠════╬═══════╬═══════════╬══════════╣
║ 1 ║ 3024 ║ orange ║ 122 ║
║ 2 ║ 2024 ║ zebra ║ 45 ║
║ 3 ║ 3010 ║ juice ║ 55 ║
║ 4 ║ 3002 ║ build ║ 17 ║
║ 5 ║ 2003 ║ car ║ 87 ║
║ 6 ║ 1610 ║ other ║ 1521 ║
║ 7 ║ 1620 ║ other ║ 200 ║
╚════╩═══════╩═══════════╩══════════╝
我希望
表biblek2_items
╔════╦═══════╦═══════════╦══════════╗
║ ID ║ catid ║ introtext ║ ordering ║
╠════╬═══════╬═══════════╬══════════╣
║ 5 ║ 2003 ║ car ║ 1 ║
║ 4 ║ 3002 ║ build ║ 2 ║
║ 3 ║ 3010 ║ juice ║ 3 ║
║ 1 ║ 3024 ║ orange ║ 4 ║
║ 2 ║ 2024 ║ zebra ║ 5 ║
╚════╩═══════╩═══════════╩══════════╝
我想
select * from biblek2_items where catid between 2001 and 3024
ORDER BY introtext ASC
我尝试失败了
DECLARE @variable int
SET @variable = 0
UPDATE `biblek2_items`
SET @variable = ordering = @variable + 1
WHERE ordering IN (SELECT ordering
FROM `biblek2_items`
WHERE catid BETWEEN 2001 AND 3024
ORDER BY `introtext` DESC)
我在论坛上读到MySQL不允许使用ORDER BY进行子请求,所以您能帮我吗
答案 0 :(得分:0)
如评论中所述:
无论如何,子查询中的ORDER BY
毫无意义,因为您没有LIMIT
。因此,将返回所有行,并且它们的顺序无关紧要,因为在主查询中的IN
已考虑到所有行。
但是您的查询还有其他问题。
改为执行此操作:
SET @row_number = 0 ;
UPDATE biblek2_items,
(select id, catid,introtext,ordering, (@row_number:=@row_number + 1) AS newordering
from biblek2_items
where catid between 2001 and 3024
ORDER BY introtext ASC
) as temp
SET biblek2_items.ordering = temp.newordering
WHERE biblek2_items.ID = temp.ID
另外,如果您有一个很大的表,并且有很多用户积极地在上面写,为避免不一致或锁定问题,我建议使用稍有不同的方法,使用临时表进行存储计算出的新顺序。
CREATE TABLE biblek2_items_TEMP (ID INT, ordering INT);
SET @row_number = 0 ;
INSERT INTO biblek2_items_TEMP
select id, (@row_number:=@row_number + 1) AS newordering
from biblek2_items
where catid between 2001 and 3024
ORDER BY introtext ASC
;
UPDATE biblek2_items, biblek2_items_TEMP
SET biblek2_items.ordering = biblek2_items_TEMP.ordering
WHERE biblek2_items.ID = biblek2_items_TEMP.ID;
DROP TABLE biblek2_items_TEMP;
在MySQL 5.7和MariaDB 10上成功测试