1. 程式人生 > 實用技巧 >mysql 解決一列資料vs多列資料 合併為一列資料

mysql 解決一列資料vs多列資料 合併為一列資料

場景如下,mysql根據使用者u_id查詢課程,不過該使用者的課程為多列資料

table users

tablecurriculums

查詢語句
select * from users as u join curriculums as c on c.u_id = u.u_id where c.u_id = 1

result

發現結果是多列資料,需求為一條資料返回,得到sql函式方法 CONCAT() 和 GROUP_CANCAT()

select u.u_id,u.nickename,CONCAT("[",GROUP_CONCAT('{"curr":"',c.c_name,'","price":',c.price,',"info":"',c.info,'"}'),"
]") as datas from users as u join curriculums as c on c.u_id = u.u_id where c.c_name like '%o%' group by u.u_id

result

 

CONCAT() 和 GROUP_CANCAT() 都是把結果拼接為一條字串,上面的例子演示為拼接為json字串


如果業務需求減少查詢次數並一次查詢多個使用者的多個數據

golang的gorm框架操作可以製作以下結構體scan為資料

type users struct {
     Uid int `gorm:"column:u_id" json:"uid"`
     ......    
}

type curriculums struct {
     Cid int `gorm:"column:c_id" json:"cid"`
     Cname string `gorm:"column:c_name" json:"title"`
     Uid int `gorm:"column:u_id" json:"uid"`
     Price float64   `gorm:"column:price" json:"
price"` } type result struct { users Datas string `gorm:"column:datas" json:"datas,omitempty"` # gorm:"column:datas" 為CONCAT() or GROUP_CANCAT() as 之後的名稱

# 需要對其中資料進行操作才用json反序列化操作Datas列資料為curriculums結構體,sql查詢時沒有對其操作
   Cu curriculums `json:"curriculums"` }

var datas []result
db.Raw("sql語句 ... CONCAT() ...").Scan(&datas)

將資料scan到結構體中,其中result.Datas 含有的資料為這次在mysql中拼接的字串,可以對其進行json反序列化操作

但是返回資料為json格式字串了,如果無需其他操作可直接由一些框架返回 datas 切片結構體資料

其中注意點為:

1.查詢使用者id為1,其中該列資料admin_del為null,得到結果CONCAT 和 GROUP_CANCAT 拼接都會返回 空字串

2.GROUP_CANCAT() 函式中可以進行另外的查詢

3.CONCAT和GROUP_CANCAT應用場景不同

例如一個使用者的多個課程查詢,如果使用 CONCAT 與一般查詢一般,返回的資料為多列

而GROUP_CANCAT則不同,會將多個列的結果拼接為一個字串,而不是像join users 返回多列資料

上面的成功例子則內部使用GROUP_CANCAT先對多個數據列拼接,外部使用 [] 拼接為json格式

4.updata 中也能使用

update curriculums set info = CONCAT(c_name,"----") where c_id = 184

-----------------------------------------------------------分割線-------------------------------------------------------------------

本筆記自用 而已,如有錯誤請指正!