【SQL Server】列转行 STUFF 函数

一:首先说简单的示例,user表数据如下:

id     name   

1      张三

2     李四

3     王五

需求:现在需要把user表里的name全部合并成一列显示出来

SELECT STUFF((SELECT ',' + name FROM user (NOLOCK) for xml path('')),1,1,'')  names

结果--> 

names

张三,李四,王五

解析:

NOLOCK:一般用于此类语句中:select * from t with(NOLOCK)

                   NOLOCK是不加锁查询,可以读取被事务锁定的数据,也称为脏读。
        说明:使当前会话的查询,不受其它会话的事务所阻塞。
                   但是这样做,就读取了其它事务的“修改后未提交的”数据。
                   也就是允许“READ UNCOMMITTED”

for xml path:个人理解就是用于对 多行的某个字段拼出的字符串进行处理  可以结合实际情况进行灵活处理

STUFF语法:STUFF ( data1 , start , length ,data2) 

                       data1:数据(可以是常量、变量,也可以是字符列或二进制数据列);

                       start:开始位置(不是下标);

                       length:长度;

                       data2:需要处理的数据(可以是常量、变量,也可以是字符列或二进制数据列);

示例:SELECT STUFF('computer', 2, 3, 'hi')    结果  == 》 chiuter

二:结合实际业务示例

现有以下业务,生成一张订单,可以选择多个商品。

订单详情表中,保存了订单主表的id。

现根据订单表左连接到订单详情表,同一条订单会得到多条数据。

select  o.*,oi.shopName from order o left join order_info  oi where o.id = oi.order_id

需求:需要同一张单据只显示一条记录,如果有多个商品信息,则行专列,逗号分隔显示

select DISTINCT o.*, STUFF((SELECT ',' +  info.shopName FROM  order_info info (NOLOCK) where info.order_id= o.id for xml path('')),1,1,'') shopName  

from order o left join order_info  oi where o.id = oi.order_id 

以上sql完美解决!!!

你可能感兴趣的:(SQL)