ฉันสามารถต่อแถว MySQL หลายแถวไว้ในฟิลด์เดียวได้ไหม


1214

ใช้MySQLฉันสามารถทำสิ่งที่ชอบ:

SELECT hobbies FROM peoples_hobbies WHERE person_id = 5;

เอาท์พุทของฉัน:

shopping
fishing
coding

แต่ฉันต้องการ 1 แถวแทน 1 คอลัมน์:

ผลลัพธ์ที่คาดหวัง:

shopping, fishing, coding

เหตุผลก็คือฉันเลือกค่าหลายค่าจากหลายตารางและหลังจากการรวมทั้งหมดฉันมีแถวมากกว่าที่ฉันต้องการ

ฉันมองหาฟังก์ชั่นในMySQL Docและมันดูไม่เหมือนCONCATหรือCONCAT_WSฟังก์ชั่นที่ยอมรับชุดผลลัพธ์

ดังนั้นใครที่นี่รู้วิธีการทำเช่นนี้?


9
ฉันเพิ่งเขียนตัวอย่างเล็ก ๆ น้อย ๆ เกี่ยวกับวิธีใช้ group_concat ซึ่งอาจเป็นประโยชน์กับคุณ: giombetti.com/2013/06/06/mysql-group_concat
Marc Giombetti

คำตอบ:


1739

คุณสามารถใช้GROUP_CONCAT:

SELECT person_id, GROUP_CONCAT(hobbies SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

ดังที่ลุดวิกระบุไว้ในความคิดเห็นของเขาคุณสามารถเพิ่มDISTINCTผู้ดำเนินการเพื่อหลีกเลี่ยงการซ้ำซ้อน:

SELECT person_id, GROUP_CONCAT(DISTINCT hobbies SEPARATOR ', ')
FROM peoples_hobbies 
GROUP BY person_id;

ตามที่แจนระบุไว้ในความคิดเห็นของพวกเขาคุณยังสามารถเรียงลำดับค่าก่อนที่จะนำไปใช้โดยORDER BY:

SELECT person_id, GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ')
FROM peoples_hobbies
GROUP BY person_id;

ตามที่ Dag ระบุไว้ในความคิดเห็นของเขามีขีด จำกัด 1024 ไบต์ต่อผลลัพธ์ หากต้องการแก้ปัญหานี้ให้เรียกใช้คิวรีนี้ก่อนการสืบค้น:

SET group_concat_max_len = 2048;

แน่นอนคุณสามารถเปลี่ยนแปลงได้2048ตามความต้องการของคุณ ในการคำนวณและกำหนดค่า:

SET group_concat_max_len = CAST(
    (SELECT SUM(LENGTH(hobbies)) + COUNT(*) * LENGTH(', ')
    FROM peoples_hobbies 
    GROUP BY person_id)
    AS UNSIGNED
);

154
เพิ่งทราบถึงข้อ จำกัด ของ 1024 ไบต์ในคอลัมน์ผลลัพธ์ (ดูพารามิเตอร์group_concat_max_len )
Dag

81
และการเพิ่มDISTINCTพารามิเตอร์คุณจะไม่ได้รับสองเท่า ... GROUP_CONCAT(DISTINCT hobbies)
ลุดวิก

3
ความต้องการของฉันคือการรับข้อมูลทั้งหมดจากหนึ่งคอลัมน์ อย่าใช้คำสั่ง GROUP BY เพื่อทำสิ่งนี้ ตัวอย่าง: SELECT GROUP_CONCAT (อีเมล SEPARATOR ',') จากผู้ใช้;
Jonathan Bergeron

1
ขอบคุณฉันไม่รู้ว่ามีการจำกัดความยาวกลุ่มของ concat ฉันต้องการสิ่งนั้นเพื่อสร้างรายชื่อสัตว์ประหลาดที่ฉันสร้างขึ้น
แพทริค

9
หากคุณต้องการงานอดิเรกจัดเรียงในผลการใช้สตริง imploded:SELECT person_id, GROUP_CONCAT(hobbies ORDER BY hobbies ASC SEPARATOR ', ') FROM peoples_hobbies GROUP BY person_id
ม.ค.

106

ดูGROUP_CONCATว่ารุ่น MySQL ของคุณ (4.1) รองรับหรือไม่ ดูเอกสารประกอบสำหรับรายละเอียดเพิ่มเติม

มันจะมีลักษณะเช่น:

  SELECT GROUP_CONCAT(hobbies SEPARATOR ', ') 
  FROM peoples_hobbies 
  WHERE person_id = 5 
  GROUP BY 'all';

11
ฉันคิดว่าgroup by 'all'ไม่จำเป็น (ยิ่งกว่านั้นไม่ต้องการ) เพราะสิ่งนี้กำหนดให้กับสตริงแถวทั้งหมดallแล้วเปรียบเทียบสตริงระหว่างแถวเหล่านี้ ฉันถูกไหม?
Krzysiek

74

ไวยากรณ์สำรองเพื่อเชื่อมต่อหลายแถวแต่ละแถวเข้าด้วยกัน

คำเตือน: โพสต์นี้จะทำให้คุณหิว

ได้รับ:

ฉันพบว่าตัวเองต้องการเลือกหลายแถวแต่ละแถว -แทนกลุ่ม - และเรียงต่อกันในบางฟิลด์

สมมติว่าคุณมีตารางรหัสผลิตภัณฑ์พร้อมชื่อและราคา:

+------------+--------------------+-------+
| product_id | name               | price |
+------------+--------------------+-------+
|         13 | Double Double      |     5 |
|         14 | Neapolitan Shake   |     2 |
|         15 | Animal Style Fries |     3 |
|         16 | Root Beer          |     2 |
|         17 | Lame T-Shirt       |    15 |
+------------+--------------------+-------+

จากนั้นคุณก็มีอาแจ็กซ์แฟนซีที่ใส่ลูกสุนัขเหล่านี้เป็นกล่องกา

13, 15, 16ผู้ใช้ที่เลือกหิวฮิปโปของคุณ ไม่มีของหวานสำหรับเธอในวันนี้ ...

หา:

วิธีสรุปการสั่งซื้อของผู้ใช้ในหนึ่งบรรทัดด้วย mysql บริสุทธิ์

สารละลาย:

ใช้GROUP_CONCATกับประโยค :IN

mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary FROM product WHERE product_id IN (13, 15, 16);

ผลลัพธ์ใด:

+------------------------------------------------+
| order_summary                                  |
+------------------------------------------------+
| Double Double + Animal Style Fries + Root Beer |
+------------------------------------------------+

โซลูชันโบนัส:

ถ้าคุณต้องการราคารวมเกินไปโยนในSUM():

mysql> SELECT GROUP_CONCAT(name SEPARATOR ' + ') AS order_summary, SUM(price) AS total FROM product WHERE product_id IN (13, 15, 16);
+------------------------------------------------+-------+
| order_summary                                  | total |
+------------------------------------------------+-------+
| Double Double + Animal Style Fries + Root Beer |    10 |
+------------------------------------------------+-------+

PS: ขอโทษถ้าคุณไม่มีIn-N-Outใกล้เคียง ...


11
แม้ว่านี่จะเป็นคำตอบที่ดี แต่ฟังดูเหมือนกับการโฆษณามากกว่าการตอบคำถามล้วนๆ ยังเป็นคำตอบที่มีรูปแบบที่ดี
FliiFe

1
ฉันจะได้รับความช่วยเหลือstackoverflow.com/q/60278898/11697039 @elbowlobstercowstand
ZUS

39

คุณสามารถเปลี่ยนความยาวสูงสุดของGROUP_CONCATค่าโดยการตั้งค่าgroup_concat_max_lenพารามิเตอร์

ดูรายละเอียดในdocumantation MySQL



25

ในกรณีของฉันฉันมีแถวของรหัสและมันเป็นสิ่งจำเป็นที่จะโยนมันเพื่อถ่านมิฉะนั้นผลที่ได้ถูกเข้ารหัสในรูปแบบไบนารี:

SELECT CAST(GROUP_CONCAT(field SEPARATOR ',') AS CHAR) FROM table

1
ขอบคุณ! หากไม่มีCASTค่าเช่นเดียว[BLOB - 14 Bytes]กับในผลลัพธ์!
Mel_T

1
ฉันจะได้รับความช่วยเหลือstackoverflow.com/q/60278898/11697039 @Fedir RYKHTIK
ZUS

16

ใช้ตัวแปรเซสชัน MySQL (5.6.13) และตัวดำเนินการที่ได้รับมอบหมายดังต่อไปนี้

SELECT @logmsg := CONCAT_ws(',',@logmsg,items) FROM temp_SplitFields a;

จากนั้นคุณจะได้รับ

test1,test11

2
เร็วกว่า GROUP_CONCAT หรือไม่
jave.web

1
ฉันทดสอบสิ่งนี้ภายใต้ PHPMyAdmin กับเซิร์ฟเวอร์ MySQL v5.6.17 ในคอลัมน์คำอธิบาย (varchar (50)) ในตารางทดสอบแต่จะส่งคืนฟิลด์ BLOB สำหรับแต่ละระเบียน:SELECT @logmsg := CONCAT_ws(',',@logmsg,description) from test
น.

14

ฉันมีคำถามที่ซับซ้อนมากขึ้นและพบว่าฉันต้องใช้GROUP_CONCATแบบสอบถามภายนอกเพื่อให้ทำงานได้:

ข้อความค้นหาดั้งเดิม:

SELECT DISTINCT userID 
FROM event GROUP BY userID 
HAVING count(distinct(cohort))=2);

imploded:

SELECT GROUP_CONCAT(sub.userID SEPARATOR ', ') 
FROM (SELECT DISTINCT userID FROM event 
GROUP BY userID HAVING count(distinct(cohort))=2) as sub;

หวังว่านี่อาจช่วยคนได้


9

สำหรับคนที่ดูวิธีใช้GROUP_CONCATกับแบบสอบถามย่อยที่นี่ - โพสต์ตัวอย่างนี้

SELECT i.*,
(SELECT GROUP_CONCAT(userid) FROM favourites f WHERE f.itemid = i.id) AS idlist
FROM items i
WHERE i.id = $someid

ดังนั้นGROUP_CONCATจะต้องใช้ภายในแบบสอบถามย่อยไม่ได้ห่อหุ้ม


1
นี่คือสิ่งที่ฉันกำลังมองหา
bumerang

7

ลองสิ่งนี้:

DECLARE @Hobbies NVARCHAR(200) = ' '

SELECT @Hobbies = @Hobbies + hobbies + ',' FROM peoples_hobbies WHERE person_id = 5;

2
นี่คือสิ่งที่ฉันได้รับ: 'ประเภทคำสั่งที่ไม่รู้จัก (ใกล้กับ "DECLARE" ที่ตำแหน่ง 0) '
Istiaque Ahmed

1

เรามีสองวิธีในการต่อคอลัมน์ใน MySql

select concat(hobbies) as `Hobbies` from people_hobbies where 1

หรือ

select group_concat(hobbies) as `Hobbies` from people_hobbies where 1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.