#mysql
#mysql
Вопрос:
У меня есть таблица biblek2 items с этими 4 столбцами :
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
- очистите столбец ordering
- измените порядок столбца ordering с шагом от 1 до n в соответствии с результатом столбца order
Я пробовал это без успеха
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, так что не могли бы вы мне помочь
Комментарии:
1. порядок BY в подзапросе в любом случае не имеет смысла, потому что вы не ОГРАНИЧИВАЕТЕ. Таким образом, будут возвращены все строки, и не имеет значения, как они упорядочены, потому что все они учитываются с помощью IN в вашем основном запросе.
2. Похоже, вы перепутали порядок car и build в своих результатах. Какую версию MySQL вы используете?
Ответ №1:
Как объяснено в комментариях : 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
Комментарии:
1. Привет, мой друг, большое тебе спасибо, результат идеальный, я сохраню твой метод с временной таблицей, очень полезный
2. @JacquesAbada круто! теперь, если это отвечает на вопрос, вы должны выполнить свои обязанности по SO и пометить его как отвеченный (и когда вы найдете ответ действительно полезным, вы также можете добавить 1 😉