ฟังก์ชั่น string_agg เอาไว้เชื่อมต่อข้อมูลสตริงใน sql ตอนที่เรา group by

ลองนึกภาพว่าเรามีข้อมูลอยู่ประมาณนี้ เป็นข้อมูลชื่อเมนูต่างๆ :drooling_face:

Screen Shot 2565-01-12 at 15.34.18

เวลาที่เราอยากจะหาราคาเฉลี่ยของเมนูแต่ละประเภท เราก็จะเขียน SQL ได้ประมาณนี้

SELECT
  category,
  AVG(price) AS average_price
FROM
  food
GROUP BY
  category

แน่นอนว่าเวลาที่เรา GROUP BY ข้อมูล เราจะต้องมี aggregate function เสมอ ซึ่งในที่นี้คือ AVG พอเราเอา SQL นี้ไปรัน ผลที่ได้คือ

Screen Shot 2565-01-12 at 15.36.51

เราก็จะได้ราคาเฉลี่ยของเมนูแต่ละประเภทมา

ทีนี้เรื่องของเรื่องก็คือว่า ปกติแล้วเรามักจะใช้ aggregate function กับข้อมูลประเภท numeric เนอะ แล้วถ้าเราอยากจะ aggregate กับข้อมูลที่เป็นสตริงบ้างล่ะ?

เราสามารถใช้ STRING_AGG ได้ครับ เท่าที่ผมรู้คือที่ BigQuery กับ PostgreSQL มีฟังก์ชั่นนี้ให้เราใช้ ซึ่งเวลาเราเอาไปใช้ก็เขียน SQL แบบนี้ได้เลย

SELECT
  category,
  STRING_AGG(name, ',') AS list_of_menus
FROM
  food
GROUP BY
  category

โดยที่ฟังก์ชั่น STRING_AGG จะรับค่าเข้ามา และรับตัว seperator เข้ามาด้วย สิ่งที่มันทำก็คือเอาค่าที่รับเข้ามา เชื่อมต่อกันด้วยตัว separator ครับ จะเป็น - เป็น , หรือเป็นค่าสตริงว่างๆ ก็ได้

พอรัน SQL ด้านบนนี้ ผลที่ได้จะเป็นแบบนี้ครับ

Screen Shot 2565-01-12 at 15.42.17

งดงามมาก :+1:

ว่าแต่ทำไปทำไมนะ? :joy: คือมันก็มีประโยชน์อยู่ครับ เช่น ถ้าเราบอกว่า 1 เมนู เนี่ย มันอยู่ได้หลาย category นะ การเขียน query ออกมาแบบนี้ เราก็จะเห็นภาพรวมได้ว่าเมนูนั้นอยู่ใน category อะไรบ้าง โดยปรับ SQL เป็นตามนี้

SELECT
  name,
  STRING_AGG(category, ',') AS list_of_categories
FROM
  `demo.food`
GROUP BY
  name

เราก็จะได้รายการของ category ที่เมนูนั้นอยู่มา

Screen Shot 2565-01-12 at 15.49.53

พอดีข้อมูลน้อยๆ นี้ไม่มีเมนูชนิดไหนอยู่มากกว่า 1 category ครับ แหะๆ แต่คิดว่าน่าจะพอนึกภาพออกเนอะ :wink: