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

หา MAX ID จาก VARCHAR ที่เก็บตัวเลขใน MySQL ด้วย CAST

เมื่อคอลัมน์ ID เก็บเป็น VARCHAR แตค่าเป็นตัวเลขทั้งหมด การใช้ MAX() ตรงๆ จะเรียงแบบ String (Lexicographic) ได้ผลผิด (เช่น '9' > '100') ต้อง CAST เป็นตัวเลขก่อน

ปัญหา: MAX บน VARCHAR

SELECT MAX(UserMarks) FROM DemoTable; -- ผล: '99' (String Compare) แต่ '9' > '100'!

สร้างตารางและข้อมูล

mysql> create table DemoTable (UserMarks varchar(20));
mysql> insert into DemoTable values('77'),('98'),('45'),('56'),('89'),('99'),('91'),('94');

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

+-----------+
| UserMarks |
+-----------+
| 77        |
| 98        |
| 45        |
| 56        |
| 89        |
| 99        |
| 91        |
| 94        |
+-----------+

คำสั่งถูกต้อง: CAST แล้ว MAX

mysql> SELECT MAX(CAST(UserMarks AS SIGNED)) AS MAX_VALUE from DemoTable;

ผลลัพธ์: 99 (ถูกต้อง)

+-----------+
| MAX_VALUE |
+-----------+
| 99        |
+-----------+

CAST Types

Syntax แบบย่อ

-- CAST (Standard SQL)
CAST(expr AS type)

-- CONVERT (MySQL Extension)
CONVERT(expr, type)

-- Shorthand (MySQL)
expr + 0          -- แปลงเป็น Number
expr * 1          -- แปลงเป็น Number

ตัวอย่างผิด/ถูก

-- ผิด: String Comparison
SELECT MAX('100', '99', '1000');  -- '99' (เพราะ '9' > '1')

-- ถูก: Numeric Comparison
SELECT MAX(CAST('100' AS UNSIGNED), CAST('99' AS UNSIGNED), CAST('1000' AS UNSIGNED)); -- 1000

Performance: Functional Index (MySQL 8.0+)

ALTER TABLE DemoTable 
ADD INDEX idx_marks_numeric ((CAST(UserMarks AS UNSIGNED)));

-- Query ใช้ Index ได้
SELECT MAX(CAST(UserMarks AS UNSIGNED)) FROM DemoTable;

Best Practice: ใช้ชนิดข้อมูลที่ถูกต้องตั้งแต่แรก

  • ID/Number → INT, BIGINT, UNSIGNED
  • หลีกเลี่ยง VARCHAR สำหรับตัวเลข
  • หากต้องเก็บ Leading Zero → ZEROFILL หรือ CHAR พร้อม CHECK
TypeRangeใช้เมื่อ
SIGNED-2^63 ~ 2^63-1Integer ทั่วไป (มีเครื่องหมาย)
UNSIGNED0 ~ 2^64-1Integer ไม่ติดลบ (ID, Count)
DECIMAL(p,s)Precision, Scaleทศนิยมแม่นยำ (Money)
DOUBLEFloating Pointวิทยาศาสตร์ (ประมาณ)