我有一個帶有自動遞增索引的 MariaDB 表,還有一個“sortorder”欄位,用于在查詢和顯示資料時控制排序順序。
例如
id title sortorder
1 this 10
2 that 30
3 other 20
4 something 25
到現在為止還挺好。我想創建一個函式來自動重新排序這些 - 好吧,不是重新排序,而是根據現有訂單重做 sortorder 列的值。運行該函式后,上述期望的結果是:
id title sortorder
1 this 10
2 that 40
3 other 20
4 something 30
這是否可以通過 MariaDB 中的 SQL 陳述句完成(我還沒有找到任何相關內容),或者我是否需要在我的 (php) 應用程式中執行此操作?
新排序順序值的邏輯基于 sortorder 列的排序。
重新編號的原因是排序順序值將在應用程式中手動維護,但偶爾從一個干凈的石板開始可能會有所幫助。用戶將接受培訓,以便在值中“留出一些空間”,以便將來進行編輯。
在第一天,“排序順序”將(手動)填充,例如 10、20、30 等。或者可能是 100、200、300 等。因此,如果他們將來需要重新排序,這將允許將一個專案的 sortorder 值更改為 25,將其放在20 和 30 的專案之間。有意義嗎?
但最終,用戶可能會把自己畫到一個角落里,或者無論如何讓他們自己感到困惑。最好為它們構建一個簡單地遍歷行并重新設定所有 sortorder 值的按鈕,以保留現有的行順序,但使 sortorder 的值重新按間隔均勻分布。
uj5u.com熱心網友回復:
這將需要在內部寫入一些子查詢。我所做的步驟如下:
- 我使用的表名是
tt. 您需要根據您的表名更改它。 - 首先是按列的排序順序獲取所有行
sortorder。 - 其次,宣告一個變數,比如說
@serial_no并1在每個選定的行上不斷增加它。這是一種老派的技術,但我發現它更具可讀性。 sortorder在這個新的父選擇查詢中分配新值。現在,我只是將它的序列號(如排名)乘以 10。您可以相應地進行調整。- 在您的更新查詢中,內部連接正在使用此選擇查詢更新的表的當前副本,并
sortorder通過在id列上匹配它們來正確更新新列值。
片段:
update tt A
inner join (
select id, title, (@serial_no := @serial_no 1) as serial_no,@serial_no * 10 as `sortorder`
from (
select *
from tt
order by sortorder asc
) temp_derived,(SELECT @serial_no := 0) as sn
) B
on A.id = B.id
set A.sortorder = B.sortorder
更新:
我剛剛意識到控制完全從用戶轉移到資料庫。如果您希望使用新的 sortorder 值更新多行,我希望提出一種解決方法,因為我從未見過使用用戶批量提交的新值更新多行(很高興知道是否存在)。
- 您需要用新值映射舊值,例如在 PHP 中的關聯陣列中。
- 在 MySQL 中啟動一個資料庫事務。
- 批量插入所有新行。
- 使用從 PHP 發送的 ID 一次性洗掉所有先前的舊行(在準備好的陳述句中,最好使用先前映射的 assoc 陣列)
- 提交交易。
- 如果出現問題,當然可以回滾。
uj5u.com熱心網友回復:
更新:此解決方案適用于 MySQL 8.0,但不適用于 MariaDB,因為 MariaDB 對 CTE 的支持不支持 UPDATE 陳述句。我將把這個解決方案留在這里給使用 MySQL 的讀者,但它不適用于 MariaDB。
mysql> select * from NoOneEverNamesTheirTableInSqlQuestions;
---- ----------- -----------
| id | title | sortorder |
---- ----------- -----------
| 1 | this | 10 |
| 2 | that | 30 |
| 3 | other | 20 |
| 4 | something | 25 |
---- ----------- -----------
mysql> with cte as (
select id, row_number() over (order by sortorder) * 10 as new_sortorder
from NoOneEverNamesTheirTableInSqlQuestions
)
update NoOneEverNamesTheirTableInSqlQuestions join cte using (id)
set sortorder = new_sortorder;
Query OK, 2 rows affected (0.01 sec)
Rows matched: 4 Changed: 2 Warnings: 0
mysql> select * from NoOneEverNamesTheirTableInSqlQuestions;
---- ----------- -----------
| id | title | sortorder |
---- ----------- -----------
| 1 | this | 10 |
| 2 | that | 40 |
| 3 | other | 20 |
| 4 | something | 30 |
---- ----------- -----------
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/371174.html
