Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

MySQL: ดึงแถวเฉพาะจากคอลัมน์สตริงผสม (ตัวอักษร, ตัวเลข, สัญลักษณ์) ด้วย CAST และ SUBSTRING

สร้างตารางและข้อมูลตัวอย่าง

mysql> create table DemoTable2006 ( UserId int NOT NULL AUTO_INCREMENT PRIMARY KEY, UserCode varchar(20) );
mysql> insert into DemoTable2006(UserCode) values('John_12');
mysql> insert into DemoTable2006(UserCode) values('John_34');
mysql> insert into DemoTable2006(UserCode) values('John_56');
mysql> insert into DemoTable2006(UserCode) values('Chris_101');
mysql> insert into DemoTable2006(UserCode) values('Chris_103');
mysql> insert into DemoTable2006(UserCode) values('Chris_106');

ข้อมูลในตาราง

+--------+-----------+
| UserId | UserCode  |
+--------+-----------+
| 1      | John_12   |
| 2      | John_34   |
| 3      | John_56   |
| 4      | Chris_101 |
| 5      | Chris_103 |
| 6      | Chris_106 |
+--------+-----------+

Query ดึงแถว John ที่มีตัวเลขมากที่สุด

mysql> select * from DemoTable2006 
    where UserCode like 'John%' 
    order by cast(substring(UserCode from 7) as signed) desc 
    limit 1;

ผลลัพธ์

+--------+----------+
| UserId | UserCode |
+--------+----------+
| 3      | John_56  |
+--------+----------+

อธิบายการทำงาน

  1. WHERE UserCode LIKE 'John%' กรองเฉพาะที่ขึ้นต้นด้วย "John"
  2. SUBSTRING(UserCode FROM 7) ดึงตัวอักษรตั้งแต่ตำแหน่งที่ 7 (หลัง "John_" = 5 ตัว + 1 = 6? รอ... "John_" = 5 chars, ตำแหน่ง 6 คือตัวแรกของตัวเลข)
  3. แก้ไข: "John_" = 5 ตัวอักษร → ตำแหน่ง 6 เริ่มตัวเลข → SUBSTRING(UserCode, 6) หรือ SUBSTRING(UserCode FROM 6)
  4. CAST(... AS SIGNED) แปลงสตริงตัวเลขเป็น Integer เพื่อเรียง 12, 34, 56 → 56 มากที่สุด
  5. ORDER BY ... DESC LIMIT 1 เรียงมาก→น้อย เอาแถวแรก

ฟังก์ชันสตริงที่ใช้บ่อย

วิธีที่ทนทานกว่า (ไม่ต้องนับตำแหน่ง)

-- ใช้ SUBSTRING_INDEX แยกด้วย _
ORDER BY CAST(SUBSTRING_INDEX(UserCode, '_', -1) AS SIGNED) DESC

-- หรือ REGEXP_SUBSTR (MySQL 8.0)
ORDER BY CAST(REGEXP_SUBSTR(UserCode, '[0-9]+$') AS SIGNED) DESC
ฟังก์ชันคำอธิบายตัวอย่าง
SUBSTRING(str, pos, len)ดึงส่วนของสตริงSUBSTRING('John_56', 6) = '56'
SUBSTRING_INDEX(str, delim, count)ดึงส่วนก่อน/หลัง DelimiterSUBSTRING_INDEX('John_56', '_', -1) = '56'
LOCATE(substr, str)หาตำแหน่ง SubstringLOCATE('_', 'John_56') = 5
CAST(expr AS TYPE)แปลงชนิดข้อมูลCAST('56' AS SIGNED) = 56