MSSQL 列記錄合併

2021-09-23 10:25:14 字數 3888 閱讀 6034

在專案開發中,有時會碰到將列記錄合併為一行的情況,例如根據地區將人員姓名合併,或根據拼音首字母合併城市等,下面就以根據地區將人員姓名合併為例,詳細講一下合併的方法。

首先,先建乙個表,並新增一些資料,建表**如下:

if object_id(n'demo') is not null

begin

drop table demo

endelse

begin

create table demo(

area nvarchar(30),

name nvarchar(20))

insert into demo(area,name)

values(n'北京',n'張三'),

(n'上海',n'李四'),

(n'深圳',n'王五'),

(n'深圳',n'錢六'),

(n'北京',n'趙七'),

(n'北京','tom'),

(n'上海','amy'),

(n'北京','joe'),

(n'深圳','leo')

endgo

建完後查詢一下,可見表中資料如下:

如果僅將name列合併,不遵循任何條件的話,我們可以採用兩種方法,第一種就是採用for xml path方式,**如下:

select ','+name from dbo.demo for xml path('')

執行結果如下:

關於for xml path的詳細介紹可參考msdn:搭配 for xml 使用 path 模式

第二種方法就是定義乙個變數用來裝載查詢的結果,**如下:

declare @namecollection nvarchar(500)

select @namecollection=isnull(@namecollection+',','')+name from dbo.demo

select @namecollection as namecollection

執行結果如下:

加了isnull是因為最開始變數@namecollection為null,為了避免「張三」前多乙個逗號(「,」)而採用的替換。

上面講了在無條件的情況下合併一列,但是在專案中幾乎不會遇到這樣的情況,一般都是根據某一列來合併另一列的資料,例如我們現在要根據area將name合併,得到這樣的結果:

有了上面的基礎,要合併成這樣的資料就容易了,我們只需要針對area列採用聚合group by或取不重複值distinct,然後根據area列合併name列,有了思路,下面就來說說如何實現,首先還是採用for xml path方式,結合自連線,首先先按area列對name列進行合併,**如下:

select area,

(select ','+name from dbo.demo where area = t.area for xml path(''))

as namecollection from dbo.demo as t

執行結果如下:

現在有兩點還沒實現,第一是結果重複了,第二是namecollection列最開始都多了乙個逗號,先去掉逗號,採用stuff 函式來進行替換,**修改如下:

select area,

stuff((select ','+name from dbo.demo where area = t.area for xml path('')),1,1,'')

as namecollection from dbo.demo as t

現在執行後結果如下:

下面就剩下去掉重複資料了,分別採用group by和distinct,**如下:

select distinct area,

stuff((select ','+name from dbo.demo where area = t.area for xml path('')),1,1,'')

as namecollection from dbo.demo as t

select area,

stuff((select ','+name from dbo.demo where area = t.area for xml path('')),1,1,'')

as namecollection from dbo.demo as t group by area

執行結果即為最終我們需要的結果,最開始在上面講到了一種用變數來裝載查詢結果實現合併一列的方法,下面詳細介紹如何採用上述方法來實現我們的需求,我們可以根據上面的方法建乙個函式,傳入乙個area引數,根據area來進行合併,返回合併值,函式如下:

create function mergebycolumn

(-- add the parameters for the function here

@area nvarchar(30)

)returns nvarchar(500)

asbegin

-- declare the return variable here

declare @nc nvarchar(500) 

-- add the t-sql statements to compute the return value here

select @nc=isnull(@nc+',','')+name from dbo.demo where area=@area

-- return the result of the function

return @nc

endgo

建好後測試下,以傳入引數為「北京」為例,執行如下**:

select dbo.mergebycolumn('北京') as namecollection

得到結果如下:

現在只需將area列也加入查詢即可,修改**如下:

select area,dbo.mergebycolumn(area) as namecollection from dbo.demo

現在也得到了重複的結果,如下:

去重複同樣可以用group by和distinct,**如下,即可以得到我們最終的結果:

select distinct area,dbo.mergebycolumn(area) as namecollection from dbo.demo

select area,dbo.mergebycolumn(area) as namecollection from dbo.demo group by area

MSSQL 列記錄合併

首先,先建乙個表,並新增一些資料,建表 如下 if object id n demo is notnull begin drop table demo endelse begin create table demo area nvarchar 30 name nvarchar 20 insert i...

MSSQL 字串分離與列記錄合併成一行混合使用

一般我們在資料庫的表字段儲存字典id,如果有多個的話一般是用,或分隔符分隔 12,14 列表顯示的時候是顯示字典名,那如果要在資料庫將字典id轉成使用者看得懂的字典名,該怎麼辦呢?我們這時候可以結合之前說到的 字串分離 split函式 和 列記錄合併成一行 這兩篇文章來完成上述功能。select s...

行記錄轉換為列記錄

clear clear all create cursor t2 學號 c 4 姓名 c 8 課目 c 10 成績 n 3 insert into t2 values 1001 張三 數學 102 insert into t2 values 1001 張三 語文 120 insert into t2...