行转列,是SQL中经常会遇到的一个问题,并且分为静态转换和动态转换,所谓静态转换即在转换的行数已知或固定;动态转换则为转换的行数不固定。

转换的方法一般采用case when语句或pivot(MSSQL 2005及以上版本)来实现。

首先来看静态转换:先准备一下测试数据,使用如下SQL语句直接生成:

If Exists (Select * From sysobjects Where 
id = OBJECT_ID('Sales') and OBJECTPROPERTY(id, 'IsUserTable') = 1)
    Begin
        Drop Table Sales
    End

Create Table Sales(
Name nvarchar(10),
Product nvarchar(12),
Quantity int)

Insert Into Sales(Name,Product,Quantity)
Values('Leo','Apple',300),
('Leo','Orange',23),
('Amy','Apple',432),
('Amy','Banana',45),
('Leo','Banana',74),
('Tomy','Apple',57),
('Tomy','Orange',92),
('Tim','Apple',76),
('Tim','Banana',45),
('Tim','Orange',159),
('Amy','Orange',610),
('Alice','Apple',245),
('Alice','Banana',342),
('Alice','Orange',138)
Go

运行后生成一个Sales表,数据如下:

现在要以商品名称(Product)的记录作为列,按照姓名来统计卖出的数量,如果某人未卖出某商品,则用“NULL”表示,即生成如下的格式:

分别用case when和pivot解决方法如下:

--case when方案
Select Name,
sum(Case When Product='Apple' Then Quantity Else NULL End) as Apple,
sum(Case When Product='Banana' Then Quantity Else NULL End) as Banana,
sum(Case When Product='Orange' Then Quantity Else NULL End) as Orange
From Sales
Group By Name

--pivot方案 sql 2005及以上版本
Select * From Sales
PIVOT
(
    SUM(Quantity) For Product in(Apple,Banana,Orange)
) as pvt

以上是静态方案,如果有一天商品又增加了strawberry,pear等,如果要实现之前的结果,按照上面的方案就又要手动去修改SQL语句,增加两种商品列,有没有一劳永逸的解决方案呢,答案当然有,就是动态SQL,结合上面的SQL语句可以看出,如果在case when中可以先找到所有的商品,然后循环生成case when语句就可以解决了;在pivot解决方案中只要将所有商品记录生成一个以“,”连接的字符串。

具体的实现语句如下:

--case when方案
Declare @sql varchar(8000)
Set @sql='Select Name'
Select @sql=@sql+' ,sum(Case When Product='''+Product+''' Then Quantity Else NULL End) as '+Product+''  
From (Select DISTINCT Product From Sales) As t    --变量遍历赋值
Set @sql=@sql+' From Sales Group By Name'
exec(@sql)

--pivot方案 sql 2005及以上版本
Declare @sql varchar(8000)
Set @sql=(Select DISTINCT ','+Product From Sales FOR XML PATH(''))
Set @sql=STUFF(@sql,1,1,'')
Set @sql='Select * From Sales
PIVOT
(
    SUM(Quantity) For Product in('+@sql+')
) as pvt'
exec(@sql)

现在随意新增商品都可以自动生成我们想要的结果了。

MSSQL—行转列的更多相关文章

  1. MSSQL—行转列

    行转列,是SQL中经常会遇到的一个问题,并且分为静态转换和动态转换,所谓静态转换即在转换的行数已知或固定:动态转换则为转换的行数不固定. 转换的方法一般采用case when语句或pivot(MSSQ ...

  2. Mssql 行转列

    ) set @sql='' --初始化变量@sql --变量多值赋值 ,,'')--去掉首个',' set @sql=' select * from( select objectid,name,jyj ...

  3. mssql 动态行转列。

    )) ,'张三' ,'李四' ,'王五' select * from #a a b ----------- ---- 张三 李四 王五 ( 行受影响) --行转列,步骤:''+张三+],[+王五+], ...

  4. mssql 数据库表行转列,列转行 比较经典

    --行列互转 /******************************************************************************************** ...

  5. 转:MSSQL SERVER行转列 列转行

    SQL Server中行列转换 Pivot UnPivot PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PI ...

  6. [MSSQL]採用pivot函数实现动态行转列

    环境要求:2005+ 在日常需求中常常会有行转列的事情需求处理.假设不是动态的行,那么我们能够採取case when 罗列处理. 在sql 2005曾经处理动态行或列的时候,通常採用拼接字符串的方法处 ...

  7. sql的行转列(PIVOT)与列转行(UNPIVOT) webapi 跨域问题 Dapper 链式查询 扩展 T4 代码生成 Demo (抽奖程序)

    sql的行转列(PIVOT)与列转行(UNPIVOT)   在做数据统计的时候,行转列,列转行是经常碰到的问题.case when方式太麻烦了,而且可扩展性不强,可以使用 PIVOT,UNPIVOT比 ...

  8. SQL Server 动态行转列(参数化表名、分组列、行转列字段、字段值)

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 实现代码(SQL Codes) 方法一:使用拼接SQL,静态列字段: 方法二:使用拼接SQL, ...

  9. T-SQL 实现行转列

    问题: 我正在寻找一种有效的方式将行转换为SQL服务器中的列 例如,通过下表如何构建出预期结果表. Id  Value   ColumnName 1   John    FirstName 2   2 ...

随机推荐

  1. Shell编程(四)Shell变量

    1. 自定义变量(仅在当前shell生效) 1.1 定义变量 #!/usr/bin/bash ip=115.239.210.27 if ping -c1 $ip &>/dev/null ...

  2. Openresty 学习笔记(二)Nginx Lua 正则表达式相关API

    ngx.re.match 语法: captures, err = ngx.re.match(subject, regex, options?, ctx?, res_table?) 环境: init_w ...

  3. request 和 response 对象

    Request 对象 request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性 常见属性 /* req.app:当callback为外部文件时,用req.app ...

  4. Eclipse 项目导航字体设置 左侧树字体

    在解压的文件下 E:\eclipse\plugins\org.eclipse.ui.themes_1.2.0.v20170517-0622\css\dark 找到  e4-dark_basestyle ...

  5. 二叉搜索树BST

    //遍历 void print(int p){ if(!p) return; print(left[p]); printf("%d\n",a[p]); print(right[p] ...

  6. Debian Security Advisory(Debian安全报告) DSA-4403-1 php7.0

    Package        : php7.0 CVE ID         : 还未申请 在广泛使用的开放源码通用脚本语言PHP中发现了多个安全问题:EXIF扩展存在多个无效内存访问的情况,并且发现 ...

  7. LOJ #6261 一个人的高三楼

    生成函数和组合数学的灵活应用 LOJ #6261 题意:求一个数列的$ k$次前缀和 $ Solution:$ 我们对原数列$ a$建生成函数$ A=\sum\limits_{i=0}^{n-1} a ...

  8. HttpWebResponse 解压gzip、deflate压缩

    需要使用到两个Stream的子类:GZipStream.DeflateStream,代码如下: public string GetResponseBody(HttpWebResponse respon ...

  9. E - Reachability from the Capital

    E - Reachability from the Capital  CodeForces - 999E 题目链接:https://vjudge.net/contest/236513#problem/ ...

  10. 省电优化之WakeLock

    https://blog.csdn.net/qfanmingyiq/article/details/54587664 boolean onStopJob (JobParameters params) ...