原文: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查询案例:多行转换为一行的更多相关文章

  1. MS SQL查询所有表行数,获取所有数据库名,表名,字段名

    1.获取所有数据库名 --SELECT Name FROM Master..SysDatabases ORDER BY Name -- 2.获取所有表名: --SELECT Name NAMEtemp ...

  2. sql 多行转换为一行

    select 字段1, [val]=( select 字段2 +',' from 表名 as b where b.字段1 = a.字段1  for xml path('')) from 表名 as a ...

  3. sql查询 ,多行数据合并成一行,并且显示合并后某一列的值拼接结果

    select  [value] = stuff((select ','+modmb003  from modmb detail where modmb=18 for xml path('')), 1, ...

  4. SQL 查询重复的行

    select * from tbsold where orderid in (select orderid from tbsold group by orderid having count(orde ...

  5. QL查询案例:取得分组 TOP-N

    [转]SQL查询案例:取得分组 TOP-N CREATE TABLE TopnTest ( name     VARCHAR(10),   --姓名 procDate DATETIME,       ...

  6. Databricks 第11篇:Spark SQL 查询(行转列、列转行、Lateral View、排序)

    本文分享在Azure Databricks中如何实现行转列和列转行. 一,行转列 在分组中,把每个分组中的某一列的数据连接在一起: collect_list:把一个分组中的列合成为数组,数据不去重,格 ...

  7. SQL查询语句去除重复行

    1.存在两条完全相同的纪录 这是最简单的一种情况,用关键字distinct就可以去掉 select distinct * from table(表名) where (条件) 2.存在部分字段相同的纪录 ...

  8. SQL实现多行合并一行 .

    ORACLE纯SQL实现多行合并一行[转] 项目中遇到一个需求,需要将多行合并为一行.表结构如下:NAME                            Null           Type ...

  9. SQL SERVER将多行数据合并成一行(转载)

    昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行 比如表中有两列数据 : ep_classes  ep_name A ...

随机推荐

  1. Sublime Text 2之Emmet插件安装及使用

    1.安装Emmet How To Install?Reffer to this link:http://www.ituring.com.cn/article/47310 2.使用Emmet--Abbr ...

  2. 【hdoj_1042】N!(大数)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1042 题目说明待求阶乘的数最大为10000,而10000!的位数为35660(这个数是上网查的),所以已经 ...

  3. 微信小程序-怎么获取当前页面的url

    getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面. https://developers.weixin.qq.com ...

  4. JS模块化规范CMD之SeaJS

    1. 在接触规范之前,我们用模块化来封装代码大多为如下: ;(function (形参模块名, 依赖项, 依赖项) { // 通过 形参模块名 修改模块 window.模块名 = 形参模块名 })(w ...

  5. bzoj 2326 矩阵快速幂

    思路:矩阵快速幂搞一搞. #include<bits/stdc++.h> #define LL long long #define fi first #define se second # ...

  6. Redis 在Centos7下配置开机自启动

    设置Redis开机启动需要如下几个步骤: 编写配置脚本 [ vim /etc/init.d/redis ] #!/bin/sh # # Simple Redis init.d script conce ...

  7. [Codeforces166B]Polygons 凸包

    大致题意: 给你一个凸多边形A,和一个任意多边形B,判断B是否在A的内部 先对A的点集建凸包,然后枚举B中的点,二分判断是否在A的内部. 二分时可用叉积判断,详细见代码 #include<cst ...

  8. 【二分答案】【DFS】【分类讨论】Gym - 100851F - Froggy Ford

    题意:河里有n块石头,一只青蛙要从左岸跳到右岸,你可以再在任意一个位置放一块石头,使得在最优方案下,青蛙单步跳的距离的最大值最小化,输出该位置. 将原图视作完全图,二分答案mid,然后在图中只保留小于 ...

  9. Android Studio NDK开发浅谈

    环境: Android Studio 1.1.0 NDK-r10d 1.新建项目--->包名:com.mxl.az.ndk 新建包含native方法的类:JniOperation.class p ...

  10. Tarjan 算法详解

    一个神奇的算法,求最大连通分量用O(n)的时间复杂度,真实令人不可思议. 废话少说,先上题目 题目描述: 给出一个有向图G,求G连通分量的个数和最大连通分量. 输入: n,m,表示G有n个点,m条边 ...