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

MySQL: การเพิ่มหมายเลขลำดับใน GROUP_CONCAT

การสร้างหมายเลขลำดับ (Numbering) ภายใน GROUP_CONCAT ตามกลุ่ม

บทความนี้แสดงวิธีใช้ตัวแปรผู้ใช้ (user-defined variables) ร่วมกับ GROUP_CONCAT เพื่อสร้างหมายเลขลำดับอัตโนมัติสำหรับแต่ละกลุ่ม (group) ใน MySQL

สร้างตารางและเพิ่มข้อมูล

mysql> create table DemoTable1627 (
    -> FirstName varchar(20),
    -> LastName varchar(20)
    -> );
Query OK, 0 rows affected (0.59 sec)

mysql> insert into DemoTable1627 values('John','Smith');
mysql> insert into DemoTable1627 values('John','Doe');
mysql> insert into DemoTable1627 values('Adam','Smith');
mysql> insert into DemoTable1627 values('Carol','Taylor');

ข้อมูลต้นฉบับ

+-----------+----------+
| FirstName | LastName |
+-----------+----------+
| John      | Smith    |
| John      | Doe      |
| Adam      | Smith    |
| Carol     | Taylor   |
+-----------+----------+

คำสั่ง SQL สำหรับเพิ่มหมายเลขลำดับใน GROUP_CONCAT

mysql> select LastName,
    -> group_concat(
    -> concat(@j := if (@p = LastName, @j + 1, if(@p := LastName,1,1)), '.', FirstName)
    -> separator ', ') FirstName
    -> from DemoTable1627
    -> group by LastName;

ผลลัพธ์

+----------+----------------+
| LastName | FirstName      |
+----------+----------------+
| Doe      | 1.John         |
| Smith    | 1.John, 2.Adam |
| Taylor   | 1.Carol        |
+----------+----------------+

อธิบายตรรกะสำคัญ

  • @p — เก็บค่า LastName ของแถวก่อนหน้า
  • @j — ตัวนับลำดับภายในกลุ่ม
  • if (@p = LastName, @j + 1, ...) — หาก LastName เดียวกับแถวก่อน ให้เพิ่มลำดับ (+1)
  • if(@p := LastName,1,1) — หากเปลี่ยนกลุ่ม ให้กำหนด @p ใหม่และรีเซ็ต @j เป็น 1
  • concat(..., '.', FirstName) — รวมหมายเลขจุดกับชื่อ

ข้อควรระวัง: การใช้ตัวแปรผู้ใช้ในลักษณะนี้อาจให้ผลลัพธ์ที่ไม่คาดคิดใน MySQL 8.0+ เนื่องจากลำดับการประเมินค่า (evaluation order) ไม่ได้รับการรับประกัน ควรพิจารณาใช้ ROW_NUMBER() OVER (PARTITION BY LastName ORDER BY FirstName) ใน MySQL 8.0 ขึ้นไปแทน ซึ่งเป็นมาตรฐานและน่าเชื่อถือกว่า