MySQL में GROUP_CONCAT और CONCAT_WS के साथ पंक्तियों को समूहित करके संयोजित करना
CONCAT_WS() (विभाजक के साथ संयोजित) और GROUP_CONCAT() को मिलाकर, आप एक कॉलम द्वारा पंक्तियों को समूहित कर सकते हैं और दूसरे कॉलम के मानों को कस्टम विभाजक के साथ एक ही स्ट्रिंग में जोड़ सकते हैं।
टेबल बनाना
mysql> CREATE TABLE DemoTable2016 (
-> UserId INT,
-> UserName VARCHAR(20)
-> );
Query OK, 0 rows affected (0.51 sec)
डुप्लिकेट UserId के साथ डेटा डालना
mysql> INSERT INTO DemoTable2016 VALUES (1, 'Chris');
Query OK, 1 row affected (0.17 sec)
mysql> INSERT INTO DemoTable2016 VALUES (2, 'Bob');
Query OK, 1 row affected (0.10 sec)
mysql> INSERT INTO DemoTable2016 VALUES (1, 'David');
Query OK, 1 row affected (0.14 sec)
mysql> INSERT INTO DemoTable2016 VALUES (2, 'Carol');
Query OK, 1 row affected (0.12 sec)
mysql> INSERT INTO DemoTable2016 VALUES (1, 'Sam');
Query OK, 1 row affected (0.14 sec)
सभी रिकॉर्ड्स देखना
mysql> SELECT * FROM DemoTable2016;
+--------+----------+
| UserId | UserName |
+--------+----------+
| 1 | Chris |
| 2 | Bob |
| 1 | David |
| 2 | Carol |
| 1 | Sam |
+--------+----------+
5 rows in set (0.00 sec)
UserId द्वारा समूहित करके नाम-ID जोड़े संयोजित करने का क्वेरी
mysql> SELECT GROUP_CONCAT(CONCAT_WS('-', UserName, UserId))
-> FROM DemoTable2016
-> GROUP BY UserId;
परिणाम
+----------------------------------------------+
| group_concat(concat_ws('-',UserName,UserId)) |
+----------------------------------------------+
| Chris-1,David-1,Sam-1 |
| Bob-2,Carol-2 |
+----------------------------------------------+
2 rows in set (0.00 sec)
फ़ंक्शन विश्लेषण
CONCAT_WS(separator, str1, str2, ...)
- WS = "With Separator"
- पहला तर्क विभाजक है
- बाद के तर्क संयोजित करने के लिए स्ट्रिंग्स हैं
- स्वचालित रूप से NULL मानों को छोड़ देता है (नियमित CONCAT के विपरीत)
CONCAT_WS('-', 'John', '25') -- 'John-25'
CONCAT_WS('-', 'John', NULL, '25') -- 'John-25' (NULL छोड़ दिया गया)
CONCAT('-', 'John', NULL, '25') -- NULL (कोई भी NULL होने पर NULL लौटाता है)
GROUP_CONCAT(expr [ORDER BY ...] [SEPARATOR ...])
- समूह के भीतर गैर-NULL मानों को संयोजित करता है
SEPARATORडिफ़ॉल्ट ',' है
संयुक्त तर्क
- आंतरिक CONCAT_WS('-', UserName, UserId): प्रत्येक पंक्ति के लिए "Name-ID" स्ट्रिंग बनाता है
- बाहरी GROUP_CONCAT(...): प्रत्येक UserId समूह के भीतर इन स्ट्रिंग्स को जोड़ता है
- GROUP BY UserId: UserId द्वारा पंक्तियों को समूहित करता है
उन्नत विविधताएं
कस्टम GROUP_CONCAT विभाजक
SELECT GROUP_CONCAT(CONCAT_WS('-', UserName, UserId) SEPARATOR '; ')
FROM DemoTable2016 GROUP BY UserId;
परिणाम: 'Chris-1; David-1; Sam-1'
समूह के भीतर क्रमबद्ध संयोजन
SELECT GROUP_CONCAT(CONCAT_WS('-', UserName, UserId) ORDER BY UserName SEPARATOR ', ')
FROM DemoTable2016 GROUP BY UserId;
अन्य एग्रीगेट्स के साथ संयोजन
SELECT
UserId,
COUNT(*) AS NameCount,
GROUP_CONCAT(CONCAT_WS('-', UserName, UserId) ORDER BY UserName SEPARATOR ', ') AS Names,
MIN(UserName) AS FirstName,
MAX(UserName) AS LastName
FROM DemoTable2016
GROUP BY UserId;
व्यावहारिक उपयोग मामले
- ईमेल सूचियाँ: उपयोगकर्ता प्रति ईमेल संयोजित करना
- टैग एग्रीगेशन: लेख प्रति टैग्स संयोजित करना
- श्रेणी पथ: पदानुक्रमित श्रेणी पथ बनाना
- ऑडिट लॉग: उपयोगकर्ता प्रति क्रियाओं का सारांश
- रिपोर्टिंग: विस्तृत पंक्तियों को सारांश पंक्तियों में संक्षिप्त करना
प्रदर्शन और सीमाएं
group_concat_max_len(डिफ़ॉल्ट 1024 बाइट्स) परिणाम को काट सकता है- बड़े समूहों के लिए:
SET SESSION group_concat_max_len = 100000; - इंडेक्स GROUP BY को गति देता है:
CREATE INDEX idx_userid ON DemoTable2016(UserId);
MySQL 8.0+ विकल्प: JSON_ARRAYAGG
SELECT
UserId,
JSON_ARRAYAGG(JSON_OBJECT('name', UserName, 'id', UserId)) AS UsersJson
FROM DemoTable2016
GROUP BY UserId;
परिणाम: [{"name": "Chris", "id": 1}, {"name": "David", "id": 1}, ...] - संरचित, पार्स करने योग्य, कोई लंबाई सीमा नहीं।