(转)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 ...
随机推荐
- Go语言入门之指针的使用
指针的使用: package main import "fmt" func zhi(){ a:= var b *int=&a //声明指针并赋值 *b=3 //改变内存地址 ...
- open()函数文件操作
open函数,该函数用于文件处理 操作文件时,一般需要经历如下步骤: (1)打开文件 (2)操作文件 一.打开文件 文件句柄 = open("文件路径","模式& ...
- SaltStack配置管理--状态间的关系(六)
一.include的引用 需求场景:用于含有多个SLS的状态,使用include可以进行多个状态的组合,将安装apache,php,mysql集合在一个sls中 [root@7mini-node1 p ...
- Map 的四种遍历方式
Map 的四种遍历方式 import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class ...
- Windows 消息循环(2) - WPF中的消息循环
接上文: Windows 消息循环(1) - 概览 win32/MFC/WinForm/WPF 都依靠消息循环驱动,让程序跑起来. 本文介绍 WPF 中是如何使用消息循环来驱动程序的. 4 消息循环在 ...
- RabbitMQ (十六) 消息队列的应用场景 (转)
原贴 : http://blog.csdn.net/cws1214/article/details/52922267 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题 ...
- centos 7 安装python3.5
1.安装编译环境 yum groupinstall 'Development Tools' yum install zlib-devel bzip2-devel openssl-devel ncure ...
- Number 和 parseInt 区别
把字符串 转换成 数字的时候, Number 有点不靠谱, 因为会对 '' 和 null 转换成0, parseInt 相对靠谱些; 判断是否是数值时, isNaN 对于字符串'2'的判断是数字, 对 ...
- .net中session的使用
什么是Session? Session即会话,是指一个用户在一段时间内对某一个站点的一次访问. Session对象在.NET中对应HttpSessionState类,表示"会话状态" ...
- 【51Nod 1238】最小公倍数之和 V3
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1238 设\(A(n)=\sum\limits_{i=1}^n\frac{ ...