現在有一個需求
我們有一張表employee EmpID EmpName ---------- ------------- 1 張山 1 張大山 1 張小山 2 李菲菲 2 李曉梅 Result I need in this format: EmpID EmpName ---------- ------------- 1 張山, 張大山, 張小山 2 李菲菲, 李曉梅
如果使用MySQL,可以很簡單的實現
selecet group_concat(empname) from employee group by empid;
但是最近公司中使用的是SQLserver,沒有group_concat的功能
最后在https://stackoverflow.com/questions/8868604/sql-group-concat-function-in-sql-server找到了答案
select distinct EmpID, (select EmpName+‘,’ from employee t2 where t2.EmpId = t1.EmpId For XML PATH('') )Concatenated from employee t1;
對於這個表是沒有問題的,本以為就這樣結束了,事實證明還是too young!
實際中又遇到了報錯:
[Err] 22018 - [SQL Server]在將 varchar 值 ',' 轉換成數據類型 int 時失敗。
很快找到原因,其中一個字段的字段類型是int類型,但是在SQL語句中,我們有一個需求是對ID進行拼接,
但是我們使用了字符串(‘,’元凶在此,再加上字段類型本身是int),還是經過一番苦苦查找和分析,找到在SQLserver中有一個字符串函數stuff和convert這兩個工具
STUFF字符串函數是將字符串插入到另一個字符串中。它會刪除開始位置第一個字符串中的指定長度的字符,然后將第二個字符串插入到開始位置的第一個字符串中,語法如下。 STUFF(<character_expression>,<start>,<lenth>,<character_expression>) <character_expression>參數是給定的字符串數據,可以是字符或二進制數據的常量,變量或列。
<start>參數是一個整數值,指定開始刪除和插入的位置,可以是BIGINT類型。如果<開始>或<長度>參數為負數,則返回NULL字符串。
如果<start>參數比第一個<character_expression>長,則返回一個NULL字符串。
<length>參數可以是BIGINT類型,它是一個整數,指定要刪除的字符數。
如果<length>比第一個<character_expression>長,則刪除發生到最后一個<character_expression>中的最后一個字符。
convert
定義和用法
CONVERT() 函數是把日期轉換為新數據類型的通用函數。
CONVERT() 函數可以用不同的格式顯示日期/時間數據。
語法
CONVERT(data_type(length),data_to_be_converted,style)
data_type(length) 規定目標數據類型(帶有可選的長度)。data_to_be_converted 含有需要轉換的值。style 規定日期/時間的輸出格式。
只使用convert,就是這樣
SELECT DISTINCT userid,( SELECT convert(varchar,area_id)+',' FROM userinfo_attarea t2 WHERE t2.employee_id=t1.employee_id FOR XML PATH('') as area_ids
輸出:
userid area_ids
1 4,5,6,
兩個一起用,為了去掉后面的符號,
SELECT DISTINCT userid,STUFF(( SELECT ','+ convert(varchar,area_id) FROM userinfo_attarea t2 WHERE t2.employee_id=t1.employee_id FOR XML PATH('') ), 1, 1, '')
輸出:
userid area_ids
1 4,5,6