(转)SQL查询案例:多行转换为一行
原文:http://www.cnblogs.com/sammon/archive/2012/05/10/2494362.html
测试表与测试数据
CREATE TABLE TestTitle (
name VARCHAR(10),
titleVARCHAR(10)
);
INSERT INTO TestTitle VALUES ('张三', '程序员');
INSERT INTO TestTitle VALUES ('张三', '系统管理员');
INSERT INTO TestTitle VALUES ('张三', '网络管理员');
INSERT INTO TestTitle VALUES ('李四', '项目经理');
INSERT INTO TestTitle VALUES ('李四', '系统分析员');
要求
对于测试数据,要求查询结果为:
张三程序员,系统管理员,网络管理员
李四项目经理,系统分析员
这种结构的结果。
思路
简单查看这个结果,很像对字符型的GROUP BY处理。
数值类型的可以SUM,但是字符类型的无法这么处理。
只好依次MAX(1) + MAX(2) + MAX(3)这种办法来处理。
实现
第一步,设置好分组的编号
SELECT
ROW_NUMBER() OVER(PARTITION BY name ORDER BY title) AS no,
name,
title
FROM
TestTitle
ORDER BY
name,
title
no name title
-------------------- ---------- ----------
1李四 系统分析员
2李四 项目经理
1张三 程序员
2张三 网络管理员
3张三 系统管理员
第二步,根据有编号的子查询,进行分组处理
SELECT
name,
CASE WHEN COUNT(title) = 1 THEN MAX(title)
WHEN COUNT(title) = 2 THEN
MAX( CASE WHEN SubQuery.no = 1 THEN title + ',' ELSE '' END )
+ MAX( CASE WHEN SubQuery.no = 2 THEN titleELSE '' END )
WHEN COUNT(title) = 3 THEN
MAX( CASE WHEN SubQuery.no = 1 THEN title + ',' ELSE '' END )
+ MAX( CASE WHEN SubQuery.no = 2 THEN title + ','ELSE '' END )
+ MAX( CASE WHEN SubQuery.no = 3 THEN titleELSE '' END )
END AS new_title
FROM
(
SELECT
ROW_NUMBER() OVER(PARTITION BY name ORDER BY title) AS no,
name,
title
FROM
TestTitle
) subQuery
GROUP BY
name
执行结果
name new_title
---------- ----------------------------------
李四 系统分析员,项目经理
张三 程序员,网络管理员,系统管理员
对于SQL Server 2005 以上版本使用FOR XML的方式
测试表与测试数据要求
与前面的一样
思路
首先把一个用户的数据,单独的读取出来
然后按照分组进行处理
实现
第一步 把一个用户的数据,单独的读取出来
SELECT
',' + title
FROM
TestTitle
WHERE
name = '张三'
FOR XML PATH('')
第二步Group By每个人
SELECT
name,
STUFF(
(
SELECT
',' + title
FROM
TestTitle subTitle
WHERE
name = TestTitle.name
FOR XML PATH('')
),
1, 1, '') AS allTitle
FROM
TestTitle
GROUP BY
name
执行结果
name allTitle
---------- --------------------------------
李四 项目经理,系统分析员
张三 程序员,系统管理员,网络管理员
对于SQL Server 2005 以上版本使用 CTE 的处理方式 (使用递归方式处理)
WITH t1 AS ( SELECT ROW_NUMBER() OVER(PARTITION BY name ORDER BY title) AS ID, name, title FROM TestTitle ), t2 AS ( SELECT t1.id,
t1.name, CAST(t1.title AS varchar(100)) AS title FROM
t1 WHERE t1.id = 1 UNION ALL SELECT t1.id, t2.name, CAST( t1.title + ',' + t2.title AS varchar(100)) AS title FROM t1, t2 WHERE t1.name = t2.name AND t1.id = (t2.id + 1) ) SELECT name, title FROM t2 WHERE NOT EXISTS ( SELECT 1 FROM t2 t22 WHERE t2.name = t22.name AND t2.id < t22.id );
name title
---------- ----------------------------------------------------------- ------------------------------- 张三 系统管理员,网络管理员,程序员
李四 项目经理,系统分析员
(2 行受影响)
对于MySQL使用 GROUP_CONCAT 函数 的方式进行处理(非常简单)
mysql> SELECT -> name, -> GROUP_CONCAT(title) AS allTitle -> FROM -> TestTitle -> GROUP BY -> name; +------+------------------------------+ | name | allTitle | +------+------------------------------+ | 李四 | 项目经理,系统分析员 | | 张三 | 程序员,系统管理员,网络管理员 | +------+------------------------------+ 2 rows in set (0.00 sec)
对于Oracle使用 WMSYS.WM_CONCAT 函数 的方式进行处理(也非常简单)
SQL> SQL> SELECT 2 name, 3 WMSYS.WM_CONCAT(title) AS allTitle 4 FROM 5 TestTitle 6 GROUP BY 7 name;
NAME ---------- ALLTITLE ------------------------------------------- 李四 项目经理,系统分析员
张三 程序员,系统管理员,网络管理员
对于 DB2 ,也是使用 CTE 递归的方式处理
WITH t1 (id, name, title) AS ( SELECT ROW_NUMBER() OVER(PARTITION BY name ORDER BY title) AS ID, name, title FROM TestTitle ), t2 (id, name, title) AS ( SELECT t1.id, t1.name, CAST(t1.title AS varchar(100)) AS title FROM t1 WHERE t1.id = 1 UNION ALL SELECT t1.id, t2.name, CAST( t1.title || ',' || t2.title AS varchar(100)) AS title FROM t1, t2 WHERE t1.name = t2.name AND t1.id = (t2.id + 1) ) SELECT name, title FROM t2 WHERE NOT EXISTS ( SELECT 1 FROM t2 t22 WHERE t2.name = t22.name AND t2.id < t22.id );
NAME TITLE
---------- --------------------------------------------------------------------- ------------------------------- SQL0347W 递归公共表表达式 "WZQ.T2" 可能包含无限循环。 SQLSTATE=01605
李四 项目经理,系统分析员
张三 网络管理员,系统管理员,程序员
已选择 2 条记录,打印 1 条警告消息。
(转)SQL查询案例:多行转换为一行的更多相关文章
- MS SQL查询所有表行数,获取所有数据库名,表名,字段名
1.获取所有数据库名 --SELECT Name FROM Master..SysDatabases ORDER BY Name -- 2.获取所有表名: --SELECT Name NAMEtemp ...
- sql 多行转换为一行
select 字段1, [val]=( select 字段2 +',' from 表名 as b where b.字段1 = a.字段1 for xml path('')) from 表名 as a ...
- sql查询 ,多行数据合并成一行,并且显示合并后某一列的值拼接结果
select [value] = stuff((select ','+modmb003 from modmb detail where modmb=18 for xml path('')), 1, ...
- SQL 查询重复的行
select * from tbsold where orderid in (select orderid from tbsold group by orderid having count(orde ...
- QL查询案例:取得分组 TOP-N
[转]SQL查询案例:取得分组 TOP-N CREATE TABLE TopnTest ( name VARCHAR(10), --姓名 procDate DATETIME, ...
- Databricks 第11篇:Spark SQL 查询(行转列、列转行、Lateral View、排序)
本文分享在Azure Databricks中如何实现行转列和列转行. 一,行转列 在分组中,把每个分组中的某一列的数据连接在一起: collect_list:把一个分组中的列合成为数组,数据不去重,格 ...
- SQL查询语句去除重复行
1.存在两条完全相同的纪录 这是最简单的一种情况,用关键字distinct就可以去掉 select distinct * from table(表名) where (条件) 2.存在部分字段相同的纪录 ...
- SQL实现多行合并一行 .
ORACLE纯SQL实现多行合并一行[转] 项目中遇到一个需求,需要将多行合并为一行.表结构如下:NAME Null Type ...
- SQL SERVER将多行数据合并成一行(转载)
昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行 比如表中有两列数据 : ep_classes ep_name A ...
随机推荐
- SCTF 2014 pwn题目分析
因为最近要去做ctf比赛的这一块所以就针对性的分析一下近些年的各大比赛的PWN题目.主防项目目前先搁置起来了,等比赛打完再去搞吧. 这次分析的是去年的SCTF的赛题,是我的学长们出的题,个人感觉还是很 ...
- 前端canvas合并图片两种实现方式
---恢复内容开始--- 需求: 有一个固定的背景图,还有一个是随机生成的二维码,合并成一张图,让用户下载. 实现一:纯手写,这里为了省事生成图片我直接给的base64,其实使用qrcode.js生成 ...
- IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) E - Bear and Forgotten Tree 2 链表
E - Bear and Forgotten Tree 2 思路:先不考虑1这个点,求有多少个连通块,每个连通块里有多少个点能和1连,这样就能确定1的度数的上下界. 求连通块用链表维护. #inclu ...
- HDU 1231.最大连续子序列-dp+位置标记
最大连续子序列 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- Docker应用系列(四)| 部署java应用
本示例基于Centos 7,假设目前使用的账号为release,拥有sudo权限. 由于Docker官方镜像下载较慢,可以开启阿里云的Docker镜像下载加速器,可参考此文进行配置. 主机上服务安装步 ...
- 5分钟掌握智联招聘网站爬取并保存到MongoDB数据库
前言 本次主题分两篇文章来介绍: 一.数据采集 二.数据分析 第一篇先来介绍数据采集,即用python爬取网站数据. 1 运行环境和python库 先说下运行环境: python3.5 windows ...
- django常见问题小结,细节容易忽视
中文URL:这个其实是很常识的东西,但是之前做web一直没注意过,在使用HttpResponseRedirect的时候,如果Redirect的URL中带中文的话,会报UnicodeEncodeErro ...
- 深入理解javascript作用域系列第四篇
前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的 ...
- Prime Number CodeForces - 359C (属于是数论)
Simon has a prime number x and an array of non-negative integers a1, a2, ..., an. Simon loves fracti ...
- Tsinsen 最长双回文串
求最长双回文串,正反建回文树求最大. 题目链接:http://www.tsinsen.com/ViewGProblem.page?gpid=A1280 By:大奕哥 #include<bits/ ...