搜尋
首頁資料庫mysql教程MySQL 中真正的字母數字/自然排序 - 為什麼答案總是遞歸?

True Alphanumeric / natural sorting in MySQL - why is the answer always recursion?

昨天我嘗試解決 MySQL 中的字母數字排序問題,但失敗了。 (在這裡閱讀那篇文章)

我確實接近了,並且有正確的概念,只是錯誤的執行。

今天,我醒來並頓悟...遞歸。

遞歸的問題在於你必須了解遞歸才能進行遞歸...而我對遞歸的理解不足以在 MySQL 中進行遞歸。

但是,透過Chat Gippity 來回進行一些操作(我的意思是讓它寫出我要求的內容,返回我要求的大約25%,修復它並將其輸入到新的聊天中,這樣就不會出現問題)不要一直重複大約2 小時)我得到了一個有效的答案!

說到重點

願我向您呈現我的絕唱、我的傑作、生活本身的答案(好吧,這是我見過的 MySQL 中真正字母數字排序的唯一有效解決方案)。

WITH RECURSIVE process_numbers AS (
    SELECT 
        data_value,
        data_value AS remaining_data,
        CAST('' AS CHAR(20000)) AS processed_data,
        1 AS iteration
    FROM test_data

    UNION ALL

    SELECT
        data_value,
        CASE 
            WHEN LOCATE(REGEXP_SUBSTR(remaining_data, '[0-9]+'), remaining_data) > 0 THEN
                SUBSTRING(
                    remaining_data,
                    LOCATE(REGEXP_SUBSTR(remaining_data, '[0-9]+'), remaining_data)
                    + LENGTH(REGEXP_SUBSTR(remaining_data, '[0-9]+'))
                )
            ELSE '' 
        END AS remaining_data,

        CONCAT(
            processed_data,
            CASE 
                WHEN LOCATE(REGEXP_SUBSTR(remaining_data, '[0-9]+'), remaining_data) > 0 THEN
                    LEFT(remaining_data, LOCATE(REGEXP_SUBSTR(remaining_data, '[0-9]+'), remaining_data) - 1)
                ELSE remaining_data
            END,
            CASE
                WHEN REGEXP_SUBSTR(remaining_data, '[0-9]+') IS NOT NULL THEN
                    RIGHT(CONCAT('0000000000', REGEXP_SUBSTR(remaining_data, '[0-9]+')), 10)
                ELSE ''
            END
        ) AS processed_data,

        iteration + 1
    FROM process_numbers
    WHERE LENGTH(remaining_data) > 0
          AND iteration 



<p>如果你想嘗試(並嘗試打破它),你可以使用這個資料庫小提琴</p>

<h2>
  
  
  那麼這是如何運作的呢?
</h2>

<p>它完成了我最初想做的事情,取出每組數字並將它們填充到總共 10 位數字。 </p>

<p>很明顯,如果你給它幾個包含 11 個連續數字的字串,如果不進行調整,它就無法工作,但除此之外它工作得很好! </p>

<p>你看,MySQL 可以正確地對數字進行排序,即使在字典排序模式下也是如此,但它有一個缺陷。 </p>

<p>它將“11”視為小於“2”,因為它一次對一個字元進行排序(有效)。所以「2」比「1」大,所以它排在第一位。然後它檢查下一個字符,此時排序不正確(至少對於數字而言)。 </p>

<p>為了更好地理解這一點,想像一下 1 實際上是字母“b”,2 是字母“c”。 </p>

<p>這就是MySQL「看到」數字的方式,它們只是另一個字元。 </p>

<p>因此,如果我有“bb”和“c”,您會<em>期望</em>“bb”出現在“c”之前。現在將數字交換回去,您就會明白為什麼「11」位於「2」之前。 </p>

<h3>
  
  
  所以這是一個駭客行為?
</h3>

<p>是的,我們透過填充將數字「向後」移動來解決這個問題。 </p>

<p>回到我們的範例,如果我們將「11」和「2」的長度填滿為 3 並將「a」用作 0,則會發生以下情況:<br>
</p>

<pre class="brush:php;toolbar:false">011 = abb
002 = aac 

注意現在排序的方式:

  • 字元 1:「a」比「a」大 - 不,它們是相同的。
  • 字元 2:「b」比「a」大 - 是的,將「a」放在「b」之前
  • 字元 3:現在無關緊要,我們已經發現了更早發生的不同且更大的事件。

所以按照這個邏輯我們現在有:

002 = aac (the second "a" comes before the second "b" in the next row)
011 = abb

這就是它的工作原理!

你要解釋一下遞歸的事情嗎?

有點。我已經用這個“繞了房子一圈”,我的知識只是表面水平,但我會嘗試一下。

問題在於 RegEx 在 MySQL 中的運作方式。 REGEX_SUBSTR 只會找到一個符合項,然後繼續為找到的所有其他符合項目傳回該符合項。這就是為什麼我昨天的解決方案無法正常運作的原因。

但是 REGEX_REPLACE 有它自己的問題,它似乎沒有正確公開匹配的字串長度(因此我們無法正確地對其進行 LPAD)

這就是為什麼我認為遞歸作為答案。

我可以使用 REGEX_SUBSTR 來獲得正確的填充行為,並且由於 RegEx 的每個循環本質上都是一個新函數調用,因此它不會「記住」上一個匹配項,因此它解決了這個問題。

如果你想簡單了解邏輯,它其實並不像看起來那麼可怕!

  • 我們循環給定的字串,尋找任何數字(整個數字,而不僅僅是單一字元)。
  • 然後我們將其從剩餘資料中刪除,這樣我們就不會再次匹配它。
  • 我們取出剛剛匹配的數字並將其填充為總共 10 位數字。
  • 然後我們搜尋字串中的下一個數字部分並重複這個過程,將processed_data建構為我們的最終字串。
  • 最後,一旦我們沒有更多的數字需要處理,我們將剩餘的字母加到processed_data的末尾以完成轉換,並將其作為sort_key返回。

然後我們可以在查詢中使用這個 sort_key 來正確排序列。

迭代部分純粹是一個保護工具,以確保它不會完全運行 MySQL 伺服器記憶體不足或在處理足夠複雜的字串時使查詢崩潰(或者邏輯中存在錯誤,這意味著它會永遠遞歸)。

這就是一個包裹!

睡在東西上會帶來新的視角,這不是很有趣嗎?

也許我應該嘗試多相睡眠,這樣我每天就可以多睡 2-3 次來解決問題,從而成為 10 倍的開發者?哈哈。

無論如何,你已經擁有了它,一個相當強大的true字母數字排序。

哦,實際上,您可能應該使用 GENERATE 或預存程序將 sort_key 轉換為資料庫上的儲存列。遺憾的是,我使用的遊樂場似乎不支持這一點,而且今天是周日,所以我將把它留給你,親愛的觀眾!

祝您週末休息愉快,度過愉快的一週。

以上是MySQL 中真正的字母數字/自然排序 - 為什麼答案總是遞歸?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
MySQL:初學者的基本技能MySQL:初學者的基本技能Apr 18, 2025 am 12:24 AM

MySQL適合初學者學習數據庫技能。 1.安裝MySQL服務器和客戶端工具。 2.理解基本SQL查詢,如SELECT。 3.掌握數據操作:創建表、插入、更新、刪除數據。 4.學習高級技巧:子查詢和窗口函數。 5.調試和優化:檢查語法、使用索引、避免SELECT*,並使用LIMIT。

MySQL:結構化數據和關係數據庫MySQL:結構化數據和關係數據庫Apr 18, 2025 am 12:22 AM

MySQL通過表結構和SQL查詢高效管理結構化數據,並通過外鍵實現表間關係。 1.創建表時定義數據格式和類型。 2.使用外鍵建立表間關係。 3.通過索引和查詢優化提高性能。 4.定期備份和監控數據庫確保數據安全和性能優化。

MySQL:解釋的關鍵功能和功能MySQL:解釋的關鍵功能和功能Apr 18, 2025 am 12:17 AM

MySQL是一個開源的關係型數據庫管理系統,廣泛應用於Web開發。它的關鍵特性包括:1.支持多種存儲引擎,如InnoDB和MyISAM,適用於不同場景;2.提供主從復制功能,利於負載均衡和數據備份;3.通過查詢優化和索引使用提高查詢效率。

SQL的目的:與MySQL數據庫進行交互SQL的目的:與MySQL數據庫進行交互Apr 18, 2025 am 12:12 AM

SQL用於與MySQL數據庫交互,實現數據的增、刪、改、查及數據庫設計。 1)SQL通過SELECT、INSERT、UPDATE、DELETE語句進行數據操作;2)使用CREATE、ALTER、DROP語句進行數據庫設計和管理;3)複雜查詢和數據分析通過SQL實現,提升業務決策效率。

初學者的MySQL:開始數據庫管理初學者的MySQL:開始數據庫管理Apr 18, 2025 am 12:10 AM

MySQL的基本操作包括創建數據庫、表格,及使用SQL進行數據的CRUD操作。 1.創建數據庫:CREATEDATABASEmy_first_db;2.創建表格:CREATETABLEbooks(idINTAUTO_INCREMENTPRIMARYKEY,titleVARCHAR(100)NOTNULL,authorVARCHAR(100)NOTNULL,published_yearINT);3.插入數據:INSERTINTObooks(title,author,published_year)VA

MySQL的角色:Web應用程序中的數據庫MySQL的角色:Web應用程序中的數據庫Apr 17, 2025 am 12:23 AM

MySQL在Web應用中的主要作用是存儲和管理數據。 1.MySQL高效處理用戶信息、產品目錄和交易記錄等數據。 2.通過SQL查詢,開發者能從數據庫提取信息生成動態內容。 3.MySQL基於客戶端-服務器模型工作,確保查詢速度可接受。

mysql:構建您的第一個數據庫mysql:構建您的第一個數據庫Apr 17, 2025 am 12:22 AM

構建MySQL數據庫的步驟包括:1.創建數據庫和表,2.插入數據,3.進行查詢。首先,使用CREATEDATABASE和CREATETABLE語句創建數據庫和表,然後用INSERTINTO語句插入數據,最後用SELECT語句查詢數據。

MySQL:一種對數據存儲的初學者友好方法MySQL:一種對數據存儲的初學者友好方法Apr 17, 2025 am 12:21 AM

MySQL適合初學者,因為它易用且功能強大。 1.MySQL是關係型數據庫,使用SQL進行CRUD操作。 2.安裝簡單,需配置root用戶密碼。 3.使用INSERT、UPDATE、DELETE、SELECT進行數據操作。 4.複雜查詢可使用ORDERBY、WHERE和JOIN。 5.調試需檢查語法,使用EXPLAIN分析查詢。 6.優化建議包括使用索引、選擇合適數據類型和良好編程習慣。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。