java动态交叉表,SqlServer如何生成动态交叉表查询

为了说明问题,我们用SqlServer自带的事例数据库(Northwind)来进行验证,所有的例子请放到Northwind中运行,我可能会省略Use语句,所引用的表,都是Northwind中的,下面我就不再说明了

这里指的交叉表,就是象Access的交叉表查询一样的效果,比如Employees表中City字段代表了城市的名称,TitleOfCourtesy代表称呼,我们希望按照City和TitleOfCourtesy的情况来统计ReportsTo字段的合计数(本统计没有任何实际意义,只是挑选一些记录包含重复内容的字段来说明情况),并显示成以下格式:(TitleOfCourtesy作为行,City作为列)

探讨这个问题之前,我们首先来看一下如何建立静态的交叉表,也就是说列数固定的交叉表,这种情况其实只要一句简单的Select查询就可以搞定:

17c135a2763225eb253f4ff92e88a664.png

SELECT

TitleOfCourtesy,

17c135a2763225eb253f4ff92e88a664.png

SUM

(

CASE

City

WHEN

'

London

'

THEN

ReportsTo

ELSE

NULL

END

)

AS

[

London City

]

,

17c135a2763225eb253f4ff92e88a664.png

SUM

(

CASE

City

WHEN

'

Redmond

'

THEN

ReportsTo

ELSE

NULL

END

)

AS

[

Redmond City

]

,

17c135a2763225eb253f4ff92e88a664.png

SUM

(

CASE

City

WHEN

'

Seattle

'

THEN

ReportsTo

ELSE

NULL

END

)

AS

[

Seattle City

]

17c135a2763225eb253f4ff92e88a664.png

FROM

Employees

GROUP

BY

TitleOfCourtesy

其中利用了CASE语句判断,如果是相应的列,则取需要统计的ReportsTo数值,否则取NULL,然后再合计

其中有两个常见问题说明一下:

a、用NULL而不用0是有道理的,假如用0,虽然求和函数SUM可以取到正确的数,但类似COUNT函数(取记录个数),结果就不对了,因为Null不算一条记录,而0要算,同理空字串("")也是这样,总之在这里应该用NULL,这样任何函数都没问题。

b、假如在视图的设计界面保存以上的查询,则会报错“没有输出列”,从而无法保存,其实只要在查询前面加上一段:Create View ViewName AS ...,ViewName是你准备给查询起的名称,...就是我们的查询,然后运行一下,就可以生成视图了,对于其他一些设计器不支持的语法,也可以这样保存。

以上查询作用也很大,对于很多情况,比如按照季度统计、按照月份统计等列头内容固定的情况,这样就行了,但往往大多数情况下列头内容是不固定的,象City,用户随时可能删除、添加一些城市,这种情况,我们就需要用存储过程来解决:

总体思路其实很简单,首先检索列头信息,形成一个游标,然后遍历游标,将上面查询语句里Case判断的内容用游标里的值替代,形成一条新的Sql查询,然后执行,返回结果,就可以了,以下是我写的一个存储过程,供大家参考:

17c135a2763225eb253f4ff92e88a664.png

CREATE

procedure

CorssTab

17c135a2763225eb253f4ff92e88a664.png

@strTabName

as

varchar

(

50

)

=

'

Employees

'

,

--

此处放表名

17c135a2763225eb253f4ff92e88a664.png

@strCol

as

varchar

(

50

)

=

'

City

'

,

--

表头分组依据字段

17c135a2763225eb253f4ff92e88a664.png

@strGroup

as

varchar

(

50

)

=

'

TitleOfCourtesy

'

,

--

分组字段

17c135a2763225eb253f4ff92e88a664.png

@strNumber

as

varchar

(

50

)

=

'

ReportsTo

'

,

--

被统计的字段

17c135a2763225eb253f4ff92e88a664.png

@strSum

as

varchar

(

10

)

=

'

Sum

'

--

运算方式

17c135a2763225eb253f4ff92e88a664.png

AS

17c135a2763225eb253f4ff92e88a664.png

17c135a2763225eb253f4ff92e88a664.png

DECLARE

@strSql

as

varchar

(

1000

),

@strTmpCol

as

varchar

(

100

)

17c135a2763225eb253f4ff92e88a664.png

EXECUTE

(

'

DECLARE corss_cursor CURSOR FOR SELECT DISTINCT

'

+

@strCol

+

'

from

'

+

@strTabName

+

'

for read only

'

)

--

生成游标

17c135a2763225eb253f4ff92e88a664.png

begin

17c135a2763225eb253f4ff92e88a664.png

SET

nocount

ON

17c135a2763225eb253f4ff92e88a664.png

SET

@strsql

=

'

select

'

+

@strGroup

+

'

,

'

+

@strSum

+

'

(

'

+

@strNumber

+

'

) AS [

'

+

@strSum

+

'

of

'

+

@strNumber

+

'

]

'

--

查询的前半段

17c135a2763225eb253f4ff92e88a664.png

17c135a2763225eb253f4ff92e88a664.png

OPEN

corss_cursor

17c135a2763225eb253f4ff92e88a664.png

while

(

0

=

0

)

17c135a2763225eb253f4ff92e88a664.png

BEGIN

17c135a2763225eb253f4ff92e88a664.png

FETCH

NEXT

FROM

corss_cursor

--

遍历游标,将列头信息放入变量@strTmpCol

17c135a2763225eb253f4ff92e88a664.png

INTO

@strTmpCol

17c135a2763225eb253f4ff92e88a664.png

if

(

@@fetch_status

<>

0

)

break

17c135a2763225eb253f4ff92e88a664.png

SET

@strsql

=

@strsql

+

'

,

'

+

@strSum

+

'

(CASE

'

+

@strCol

+

'

WHEN

'''

+

@strTmpCol

+

'''

THEN

'

+

@strNumber

+

'

ELSE Null END) AS [

'

+

@strTmpCol

+

'

'

+

@strCol

+

'

]

'

--

构造查询

17c135a2763225eb253f4ff92e88a664.png

END

17c135a2763225eb253f4ff92e88a664.png

SET

@strsql

=

@strsql

+

'

from

'

+

@strTabname

+

'

group by

'

+

@strGroup

--

查询结尾

17c135a2763225eb253f4ff92e88a664.png

17c135a2763225eb253f4ff92e88a664.png

EXECUTE

(

@strsql

)

--

执行

17c135a2763225eb253f4ff92e88a664.png

IF

@@error

<>

0

RETURN

@@error

--

如果出错,返回错误代码

17c135a2763225eb253f4ff92e88a664.png

CLOSE

corss_cursor

17c135a2763225eb253f4ff92e88a664.png

DEALLOCATE

corss_cursor

RETURN

0

--

释放游标,返回0表示成功

17c135a2763225eb253f4ff92e88a664.png

17c135a2763225eb253f4ff92e88a664.png

17c135a2763225eb253f4ff92e88a664.png

17c135a2763225eb253f4ff92e88a664.png

end

17c135a2763225eb253f4ff92e88a664.png

GO

几点说明:

a、这是一个通用存储过程,使用时@strTabName、@strCol、@strGroup、@strNumber、@strSum几个变量设置一下就可以用到其他表上,其中结果集的第二列我加了个合计列

b、为了测试方便,我在存储过程中设置了默认值,就是前面提到的Employees表,这样直接运行时就可以出来我上面提到的结果。

c、使用时,可以把上面的代码复制到企业管理器的查询设计界面Sql窗格,或者查询分析器里运行一下(注意正确选择NorthWind数据库),就可以生成一个存储过程:CorssTab,然后直接运行CorssTab,如果出现本文前面类似的窗格,就表示运行成功了。

d、假如用于其它表,首先需要在你的用户数据库里生成此存储过程(当然也可以放到Master里,然后再加个变量:@DataBase,赋值为数据库名称,然后在上面代码打开指定数据库,这样所有的数据库都可以调用它),当你调用时,采取以下格式:

CorssTab @strTabName = 'Orders', @strCol = 'DATEPART(yy, OrderDate)',@strGroup = 'CustomerID', @strNumber = 'OrderID', @strSum = 'Count'

上面这条语句统计了NorthWind中Orders表里每个客户年度订单数量,大家可以运行试一下效果,虽然列头显示的名称不恰当,但基本效果出来了,相信大家通过对我的代码再作简单修改,可以达到满意的交叉表效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461078.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Canvas Clock

这两天在看html5的canvas,实现了上面那个东西 需要注意的地方&#xff1a; 1.canvas的sava()和restore()理解和使用 2.canvas的translate scale rotate ..的使用&#xff0c;每个变化都应该清楚圆心和角度..看&#xff1a;http://blog.sina.com.cn/s/blog_8fab526c01015tqs.htm…

CentOS 6.3 下用ntfs-3g挂载Windows NTFS分区

2019独角兽企业重金招聘Python工程师标准>>> 默认情况下&#xff0c;CentOS 6.3不支持Widows NTFS硬盘分区读写&#xff0c;要想把NTFS格式的磁盘挂载到CentOS 6.3下面需要安装第三方的插件ntfs-3g&#xff0c;这里我们采用编译安装插件。 1、安装编译器&#xff0c…

C++的const修饰

2019独角兽企业重金招聘Python工程师标准>>> C的const修饰 ‍const的两个用途‍ &#xff08;1&#xff09;可以定义 const 常量 &#xff08;2&#xff09;const 可以修饰函数的参数、返回值. const的好处 &#xff08;1&#xff09;便于进行类型检查&#xff0c;…

心率变异性 matlab,心率变异性好的功率谱分析方面的问题

本帖最后由 天路 于 2018-2-25 21:16 编辑本人正在学习心率变异性方面的内容&#xff0c;但是按照文献上的方法做出来的结果并不是很理想&#xff0c;文献上说的是心率变异性的频率的范围是0.4以内&#xff0c;但是我做的功率谱上显示频率分布在整个频域内&#xff0c;试了很多…

决策树php,决策树模型组合之随机森林与GBDT

前言&#xff1a;决策树这种算法有着很多良好的特性&#xff0c;比如说训练时间复杂度较低&#xff0c;预测的过程比较快速&#xff0c;模型容易展示(容易将得到的决策树做成图片展示出来)等。但是同时&#xff0c;单决策树又有一些不好的地方&#xff0c;比如说容易over-fitti…

关于uboot的简介——uboot的目录结构

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 不同版本的uboot&#xff0c;或者同一版本不同人员移植的uboot&#xff0c;目录结构和文件内容都会有所不同&#xff0c;也就是说&#xff0c;可以根据需要去添加、删除或者更改目录结构。在以三星的…

Photoshop绘制植物大战僵尸中的食人花

本人意见&#xff1a;我打算使用本文中的食人花形象作为我的一次讲课中的主要参考。我想说明的是&#xff0c;通过FLASH和PS都能够轻松地绘制出如本文所描述的食人花卡通效果。独立游戏开发者如果安排好时间&#xff0c;完全可以通过1-2个月掌握FLASH和PS绘制&#xff08;想精通…

uboot源码——uboot启动内核过程总结

总结的思维导图&#xff0c;其下载地址&#xff1a;Uboot启动.mmap_免费高速下载|百度网盘-分享无限制 第一阶段&#xff1a;汇编阶段&#xff0c;即start.S文件的工作。 第二阶段&#xff1a;C代码阶段&#xff0c;即start_armboot函数的工作。 值得一提的是&#xff0c;star…

虚拟化运行[OpenStack] VMWare产品介绍

最近使用开发的过程中出现了一个小问题&#xff0c;顺便记录一下原因和方法--虚拟化运行 世界上最早研制虚拟化软件的厂商之一。目前是是寰球桌面到数据中心虚拟化解决方案的引导厂商。中文名“威睿”&#xff0c;纽约证券交易所代码&#xff1a;VMW。总部设在加利福尼亚州的帕…

内核源码——kernel启动过程的思维导图

参考博客 内核源码——汇编阶段的head.S文件_天糊土的博客-CSDN博客___head汇编 内核源码——C语言阶段的start_kernel函数_天糊土的博客-CSDN博客_start_kernel 思维导图 kernel启动过程的思维导图下载地址&#xff1a;内核启动过程.mmap

oracle的等保,3.Oracle 检查(部分)

这是3级等保中oracle的检查方法&#xff0c;剩下的检查项可通过询问的方式进行检查。1.身份鉴别a.1 查看数据库用户select username,account_status from dba_users;b.1 检查用户的profileselect username,account_status,profile from dba_users;b.2 检查密码策略select profi…

Linux字符设备驱动剖析

以下内容整理于Linux字符设备驱动剖析&#xff0c;如有侵权请告知删除 。 一、应用层的程序 应用程序一般都是open打开设备文件&#xff0c;read、write、ioctl设备文件&#xff0c;最后close设备文件退出。 int main(int argc ,char *argv[]) { unsigned char val[1] 1; …

php处理form多文件上传,ajax利用FormData、FileReader实现多文件上传php获取

前台代码(注意&#xff0c;不需要用到form标签)&#xff1a;a. html部分&#xff1a;b. js部分&#xff1a;c. 完整代码&#xff1a;function loadDoc(file,data,asynctrue){if(window.XMLHttpRequest){ // code for IE7, Firefox, Chrome, Opera, Safarixmlhttpnew XMLHttpReq…

Linux设备文件的创建和mdev

以下内容源于微信公众号嵌入式企鹅圈&#xff0c;有格式内容上的修改&#xff0c;如有侵权请告知删除。 本文将从代码级去理解Linux设备类和设备文件的创建过程。 一、设备类相关知识 设备类是虚拟的&#xff0c;并没有直接对应的物理实物&#xff0c;只是为了更好地管理同一类…

JDK源码 - BitSet的实现

java.util.BitSet是个很有趣的类&#xff0c;了解其内部实现对正确的使用非常重要。 对象构造&#xff1a; Java代码 private final static int ADDRESS_BITS_PER_WORD 6; private final static int BITS_PER_WORD 1 << ADDRESS_BITS_PER_WORD; private long[] wor…

Sharepoint学习笔记—ECM系列--根据位置设置的默认元数据值(Location-Based Metadata Defaults)...

如果有这样一个需求&#xff1a;客户在一个SharePoint 2010的站点的document library中创建了不同的文件夹FolderA和FolderB&#xff0c;对于上传到此文件夹的文件记录中有某一个列ColumnM,现在他实现当上传文件到不同的文件夹FolderA或FolderB时&#xff0c;列ColumnM使用不同…

博客园的CSRF

CSRF全称 Cross Site Request Forgery&#xff0c;跨站请求伪造。通俗理解&#xff1a;攻击者盗用当前用户身份&#xff0c;发请当前用户的恶意请求&#xff1a;如邮件&#xff0c;银行转账等。 CSRF原理 CSRF过程 登录网站A&#xff0c;生成本地Cookie信息&#xff1b;登录危…

开发板——在X210开发板上进行裸机开发的细节

以下内容是学习裸机开发过程中的一些细节内容的记录。 1、汇编语言函数细节 用汇编写的函数&#xff0c;末尾应该添加mov pc,lr语句。 2、裸机代码相关文件 3、关于链接地址 4、关于重定位的理解 &#xff08;1&#xff09;在sram内部重定位 这是在sram内部重定位&#xff0c;因…