很有意思的SQL多行数据拼接

要实现的SQL查询很原始:

要求从第一个表进行查询得到第二个表格式的数据,上网查询之后竟然能写出下面的SQL:
复制代码 代码如下:
select * from userino

SELECT * FROM(
SELECT DISTINCT userpart
FROM userino
)A
OUTER APPLY(
SELECT
[usernames]= replace(replace(replace((SELECT username as value FROM userino N
WHERE userpart = A.userpart order by n.username asc FOR XML AUTO),'"/><N value="','/')
,'<N value="',''),'"/>','')
)N
OUTER APPLY(
SELECT
[username_cns]= replace(replace(replace((SELECT username_cn as value FROM userino M
WHERE userpart = A.userpart order by m.username asc FOR XML AUTO),'"/><M value="','/')
,'<M value="',''),'"/>','')

)M

现将SQL进行一下分析:

总共使用到的点有:OUTER APPLY,FOR XML AUTO。由于对SQL Server没有很深的研究,所以记录一下

OUTER APPLY 是SQL2005开始支持的一种查询方法,类似于连接查询,是将两个查询结果进行拼接,但是奇特的是,使用OUTER APPLY竟然能够在Apply后面的查询中使用前面已经得到的查询结果。

如:
复制代码 代码如下:
select * from
(select * from userino) A
cross join (select username from userino
where username = A.username )B

select * from
(select * from userino) A
join (select username from userino ) B on a.username = b.username

select * from
(select * from userino) A
OUTER APPLY (select username from userino
where username = A.username ) B

第一段SQL显然是错的,有两个原因:1.Cross Join本来就是无条件的,2. SQl Server会爆出如下错误:

The multi-part identifier "A.username" could not be bound.

大家可能会说有条件的Join查询本来就不是这样写的,应该写为第二条SQL这样的样子,其实这样写和第三条SQL中使用Outer apply 实现的效果是一样的

可是 Outer Apply还能实现如下的效果
复制代码 代码如下:
select * from
(select * from userino) A
OUTER APPLY (select [value] = a.username+'test' ) B

这个恐怕直接使用join就有点麻烦了,上面的例子也许没什么意义,其实SQL2005提出Apply连接方法主要是为了在连接查询中使用已经执行的查询语句的结果

除了“OUTER APPLY”,SQL Server还有CROSS APPLY,之间的区别主要是在Null值的处理上

FOR XML AUTO 主要用于将SQL的查询结果直接返回成XML语句,For Xml 除了auto外 还有RAW和EXPLICIT,详见《超级简单:使用FOR XML AUTO控制XML输出》

在文章刚开始提出的SQL文,就是使用了上面的两个特性,首先使用Outer Apply来实现类似于使用userpart进行分组的效果,来分别筛选出各个userpart中的user,然后由于筛选出的结果是多行,所以使用 for xml 来把多行数据拼接成xml,最后很二的对xml进行拆分....

综上,感觉这种实现方式比较独特,又学习了SQL Server中的一些特性,和大家分享一下

时间: 2024-09-23 23:10:57

很有意思的SQL多行数据拼接的相关文章

很有意思的SQL多行数据拼接_MsSql

要实现的SQL查询很原始: 要求从第一个表进行查询得到第二个表格式的数据,上网查询之后竟然能写出下面的SQL: 复制代码 代码如下: select * from userino SELECT * FROM( SELECT DISTINCT userpart FROM userino )A OUTER APPLY( SELECT [usernames]= replace(replace(replace((SELECT username as value FROM userino N WHERE u

sql server多行数据拼接的实例方法_MsSql

1.表结构id type productCode1 铅笔 00012 铅笔 00023 铅笔 00034 钢笔 00045 钢笔 00056 钢笔 00047 圆珠笔 00078 圆珠笔 00089 圆珠笔 00072.自定义函数fun 复制代码 代码如下: GO/****** Object:  UserDefinedFunction [dbo].[fun]    Script Date: 11/22/2011 16:09:45 ******/SET ANSI_NULLS ONGOSET QUO

sql server多行数据拼接的实例方法

1.表结构 id type productCode 1 铅笔 0001 2 铅笔 0002 3 铅笔 0003 4 钢笔 0004 5 钢笔 0005 6 钢笔 0004 7 圆珠笔 0007 8 圆珠笔 0008 9 圆珠笔 0007 2.自定义函数fun 复制代码 代码如下: GO /****** Object:  UserDefinedFunction [dbo].[fun]    Script Date: 11/22/2011 16:09:45 ******/ SET ANSI_NULL

as-sql查询行数据里不同字段有相同数据的记录

问题描述 sql查询行数据里不同字段有相同数据的记录 create table meiyong ( id int identity(1,1), se_id varchar(100), sp_id varchar(100), xx varchar(100), yy varchar(100) ) insert into meiyong values('谁是大哥','不知道','aa','bb') insert into meiyong values('我是哥哥','我是哥哥','q','ma') i

文本框-急!.net中如何使用虚拟表储存从sql中查出来的整行数据。请各位前辈教诲。

问题描述 急!.net中如何使用虚拟表储存从sql中查出来的整行数据.请各位前辈教诲. 具体功能是这样的:我想通过文本框输入在数据库中查询.并把在数据库中查询的结果通过datatable保存下来.!!!!!前辈们是把在文本框n次输入查询的结果都保存在datatable的虚拟表里.整行的整行的那种. 解决方案 你把查询出来的数据放在一个对象集合中或者数据集中,存在xml中 或者存在session中都可以,有很多种方式都可以实现,重要的是你要把数据存入虚拟的内存中就OK 了 解决方案二: 创建一个m

SQL Server将一列的多行内容拼接成一行的实现方法_MsSql

下面大家先看下示例代码: 示例 昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行,比如表中有两列数据 : 类别 名称 AAA 企业1 AAA 企业2 AAA 企业3 BBB 企业4 BBB 企业5 我想把这个表变成如下格式: 类别 名称 AAA 企业1,企业2,企业3 BBB 企业4,企业5 一开始挺头疼的(会了的肯定没有这种感觉,不会那必须是头疼啊(*^__^*) ),从网上找了点资料,算是找到一种比较简单方便

SQL Server将一列的多行内容拼接成一行的实现方法

下面大家先看下示例代码: 示例 昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行,比如表中有两列数据 : 类别 名称 AAA 企业1 AAA 企业2 AAA 企业3 BBB 企业4 BBB 企业5 我想把这个表变成如下格式: 类别 名称 AAA 企业1,企业2,企业3 BBB 企业4,企业5 一开始挺头疼的(会了的肯定没有这种感觉,不会那必须是头疼啊(*^__^*) ),从网上找了点资料,算是找到一种比较简单方便

更新多行数据,然后把更新的结果读出来,这样的 SQL 要怎么写?

考虑这样一种场景,或许还挺常见的:我们需要在关系数据库中更新一行或多行数据的多个字段,更新完了还不算,还得拿到被更新的某一个字段的结果. 再考虑这样一种场景:我们需要在关系数据库中更新一行或多行数据的多个字段,更新完了还不算,还得拿到这批被更新的记录的主键,以便操作其他的有关联的表. 这么说也许太抽象,就拿点赞计数来打个比方(做为点赞狂魔的我,前不久才在朋友的 博文 下面强行点了 666 个赞). 假设有这样一张表,就叫 likes 好了,记录了一个网站里面每个能被点赞的对象被赞的次数.id 是

sql server-SqlServer 2008 R2 如何多行数据输出为一行

问题描述 SqlServer 2008 R2 如何多行数据输出为一行 大虾们,我这边现在有这样的一个需求,要从网页上导出数据,即从数据库里面找寻出数据再导出,两张表分别有AdminID关联,表里面的数据如图: 请问这样的能实现吗?求语句如何实现? 解决方案 使用xml path select name,adminid,(select Content from 资源跟踪表 where adminid=资源表.adminid from FOR XML PATH('')) Content from 资