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

VB+MS SqlServer,是我们目前开发数据库应用系统最常用的模式,翻翻以前的老帖子,有一些SqlServer的问题经常被提出来,但正确解答甚少,现把我对这些问题的见解贴出来,这次先讲讲动态交叉表的问题

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

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

TitleOfCourtesy LondonCity RedmondCity SeattleCity
Dr.      
Mr. 12    
Mrs.   2  
Ms. 5   4

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

SELECT TitleOfCourtesy,
  SUM(CASE City WHEN 'London' THEN ReportsTo ELSE NULL END) AS [London City],
 SUM(CASE City WHEN 'Redmond' THEN ReportsTo ELSE NULL END) AS [Redmond City],
 SUM(CASE City WHEN 'Seattle' THEN ReportsTo ELSE NULL END) AS [Seattle City]
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查询,然后执行,返回结果,就可以了,以下是我写的一个存储过程,供大家参考:

CREATE procedure CorssTab
@strTabName as varchar(50) = 'Employees', --此处放表名
@strCol as varchar(50) = 'City',                       --表头分组依据字段
@strGroup as varchar(50) = 'TitleOfCourtesy',--分组字段
@strNumber as varchar(50) = 'ReportsTo',    --被统计的字段
@strSum as varchar(10) = 'Sum'                     --运算方式
AS

DECLARE @strSql as varchar(1000), @strTmpCol as varchar(100)
EXECUTE ('DECLARE corss_cursor CURSOR FOR SELECT DISTINCT ' + @strCol + ' from ' + @strTabName + ' for read only ') --生成游标
begin
  SET nocount ON
  SET @strsql ='select ' + @strGroup + ', ' + @strSum + '(' + @strNumber + ') AS [' + @strSum + ' of ' + @strNumber + ']' --查询的前半段

OPEN corss_cursor
  while (0=0)
  BEGIN
    FETCH NEXT FROM corss_cursor --遍历游标,将列头信息放入变量@strTmpCol
    INTO @strTmpCol
    if (@@fetch_status<>0) break
          SET @strsql = @strsql + ', ' + @strSum + '(CASE ' + @strCol + ' WHEN ''' + @strTmpCol + ''' THEN ' + @strNumber + ' ELSE Null END) AS [' + @strTmpCol + ' ' + @strCol + ']' --构造查询
  END
        SET @strsql = @strsql + ' from ' + @strTabname + ' group by ' + @strGroup --查询结尾

EXECUTE(@strsql) --执行

IF @@error <>0 RETURN @@error --如果出错,返回错误代码
  CLOSE corss_cursor
  DEALLOCATE corss_cursor RETURN 0 --释放游标,返回0表示成功

end
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表里每个客户年度订单数量,大家可以运行试一下效果,虽然列头显示的名称不恰当,但基本效果出来了,相信大家通过对我的代码再作简单修改,可以达到满意的交叉表效果。

下次我再讲讲,如何给查询的记录集自动加行号


动态SQL的使用例子, 行列转换

drop   table  #test
create   table  #test(name   nvarchar ( 20 ),type   nvarchar ( 20 ),category   nvarchar ( 20 ))
select   *   from  #test
insert   into  #test(name,type,category)  values  ( ' n1 ' , ' t1 ' , ' c1 ' );
insert   into  #test(name,type,category)  values  ( ' n2 ' , ' t1 ' , ' c2 ' );
insert   into  #test(name,type,category)  values  ( ' n3 ' , ' t2 ' , ' c1 ' );
insert   into  #test(name,type,category)  values  ( ' n4 ' , ' t3 ' , ' c3 ' );
insert   into  #test(name,type,category)  values  ( ' n5 ' , ' t2 ' , ' c4 ' );
insert   into  #test(name,type,category)  values  ( ' n6 ' , ' t3 ' , ' c5 ' );
insert   into  #test(name,type,category)  values  ( ' n1 ' , ' t1 ' , ' c1 ' );

-- select category,name,sum(case when type='t1' then 1 else 0 end),sum(case when type='t2' then 1 else 0 end),sum(case when type='t3' then 1 else 0 end) from #test group by name,category
-- 如果type不固定
-- 使用動態SQL語句 
Declare   @S   Varchar ( 8000 )
Select   @S   =   ' Select     category, name '
Select   @S   =   @S   +   ' , SUM(Case type When  '''   +  type  +   '''  Then 1 Else 0 End) As  '   +  type
From  #TEST  Group   By  type
Select   @S   =   @S   +   '  From #TEST Group By category, name Order By category, name '
print   @S
EXEC ( @S )
GO

-- 测试数据   行转列
   Create     table    test   (name    char ( 10 ),km    char ( 10 ),cj    int )   
   insert    test    values ( ' 张三 ' , ' 语文 ' , 80 )   
   insert    test    values ( ' 张三 ' , ' 数学 ' , 86 )   
   insert    test    values ( ' 张三 ' , ' 英语 ' , 75 )   
   insert    test    values ( ' 李四 ' , ' 语文 ' , 78 )   
   insert    test    values ( ' 李四 ' , ' 数学 ' , 85 )   
   insert    test    values ( ' 李四 ' , ' 英语 ' , 77 )   
    
   -- 查询   
   declare     @sql     varchar ( 8000 ), @s1     varchar ( 8000 )   
   select     @sql     =     '' , @s1 = ''    
    
   select     @sql     =     @sql +     ' ,[ ' + km + ' ]=sum(case   km   when    ''' + km + '''    then   cj   else   0   end) '    
  , @s1 = @s1 + ' ,sum(case   km   when    ''' + km + '''    then   cj   else   0   end)/sum(case   km   when    ''' + km + '''    then   1   else   0   end) '    
   from    test     
   group     by    km   
   exec ( ' select   name=case   grouping(name)   when   1   then    '' 全班总分 ''    else   name   end ' + @sql + ' ,小计=sum(cj)   
  from   test   
  group   by   name   with   rollup   
  union   all   
  select    '' 全班平均分 ''' + @s1 + ' ,sum(cj)/count(distinct   name)   
  from   test ' )   
   go    
    
   -- 删除测试   
   drop     table    test
-- MS SQL2000下月份不固定的動態寫法
Create   Table  TEST
(class     Nvarchar ( 10 ),
 name     Nvarchar ( 10 ),
 年份     Int ,
  [ 1月 ]          Varchar ( 10 ),
  [ 2月 ]          Varchar ( 10 ),
  [ 3月 ]          Varchar ( 10 ))
Insert  TEST  Select  N ' 一班 ' ,N ' 张三 ' , 2007 , ' 5元 ' , ' 2元 ' , ' 5元 '
Union   All   Select  N ' 一班 ' ,N ' 李四 ' , 2006 , ' 3元 ' , ' 0元 ' , ' 1元 '
Union   All   Select  N ' 二班 ' ,N ' 王五 ' , 2007 , ' 0元 ' , ' 0元 ' , ' 1元 '
GO
Declare   @S   Nvarchar ( 4000 )
Select   @S   =   ''
Select   @S   =   @S   +   '  Union Select class, name, 年份,  '''   +  Name  +   '''  As 月份, [ '   +  Name  +   ' ] As 元  From TEST  '  
From  SysColumns  Where  ID  =   OBJECT_ID ( ' TEST ' )  And  Name  Like   ' %月 '   Order   By  Name
Select   @S   =   Stuff ( @S ,  1 ,  7 ,  '' )
Print   @S
EXEC ( @S )
GO
Drop   Table  TEST
-- 动态月份2005 处理如下:
-- 测试环境
create   table  tb_tb(class  varchar ( 10 ),name  varchar ( 10 ),年份  varchar ( 10 ), [ 1月 ]   varchar ( 10 ), [ 2月 ]   varchar ( 10 ), [ 3月 ]   varchar ( 10 ))
insert   into  tb_tb  select   ' 一班 ' , ' 张三 ' , ' 2007 ' , ' 5元 ' , ' 2元 ' , ' 5元 '
union   all   select   ' 一班 ' , ' 李四 ' , ' 2006 ' , ' 3元 ' , ' 0元 ' , ' 1元 '
union   all   select   ' 二班 ' , ' 王五 ' , ' 2007 ' , ' 0元 ' , ' 0元 ' , ' 1元 '
-- 计算月份:
declare   @月份   varchar ( 100 )
set   @月份 = '' ;
select   @月份 = @月份 + ' ,[ ' + name + ' ] '   from  sys.columns  where   object_id = object_id ( ' tb_tb ' )
and  name  like   ' %月 '
set    @月份 = stuff ( @月份 , 1 , 1 , '' )
-- 交叉表处理
exec ( '
select * from tb_tb
unpivot
    ( 金额 for 月份 in ( ' + @月份 + ' )
) unpt
where 金额<> '' 0元 ''
' )
-- 删除测试环境
drop   table  tb_tb
-- 建立測試環境
Create   Table  表1
( [ id ]      Int ,
  [ 名称 ]      Nvarchar ( 20 ))
Insert  表1  Select   1 ,       N ' 名称1 '
Union   All   Select   2 ,       N ' 名称2 '
Union   All   Select   3 ,       N ' 名称3 '

Create   Table  表2
( [ id ]          Int ,
  [ 时间 ]      Nvarchar ( 10 ),
  [ 地点 ]      Nvarchar ( 10 ))
Insert  表2  Select   1 ,          N ' 5日 ' ,        N ' 上海 '
Union   All   Select   1 ,          N ' 9日 ' ,        N ' 北京 '
Union   All   Select   1 ,          N ' 20日 ' ,      N ' 天津 '
Union   All   Select   2 ,          N ' 8日 ' ,        N ' 杭州 '
Union   All   Select   2 ,          N ' 19日 ' ,       N ' 广州 '
Union   All   Select   3 ,          N ' 8日 ' ,        N ' 深圳 '
GO
-- 創建函數
Create   Function  F_TEST( @id   Int )
ReturnS   Nvarchar ( 4000 )
As
Begin
     Declare   @S   Nvarchar ( 4000 )
     Select   @S   =   ''
     Select   @S   =   @S   +   ' ; '   +  时间  +   ' - '   +  地点  From  表2  Where  id  =   @id
     Select   @S   =   Stuff ( @S ,  1 ,  1 ,  '' )
     Return   @S
End
GO
-- 測試
Select
    id,
    dbo.F_TEST(id)  As   [ 时间、地点 ]
From
    表1
GO
-- 刪除測試環境
Drop   Table  表1, 表2
Drop   Function  F_TEST

把列变成行的sql语句

线有如下表:

科目   分数    姓名
  语文     88      董兆
  数学    95       董兆
  英语     89      董兆

语文     69      婵娟
  数学    95       婵娟
  英语     89      婵娟

语文     69      李慧
  数学    95       李慧
  英语     89      李慧

一条sql语句,查询结果是

李慧 婵娟 董兆
  语文   69    69   88
  数学   95     95  95
  英语   89    89   89
sql语句如下:

create table k(科目 varchar(50),分数 int,姓名 varchar(50))
insert k select '语文',88,'董兆'
union all select '数学',95,'董兆'
union all select '英语',89,'董兆'
union all select '语文',69,'婵娟'
union all select '数学',95,'婵娟'
union all select '英语',89,'婵娟'
union all select '语文',69,'李慧'
union all select '数学',95,'李慧'
union all select '英语',89,'李慧'

declare @s varchar(8000)
set @s='select 科目'
select @s=@s+',['+姓名+']=sum(case 姓名 when '''+姓名+''' then 分数 else 0 end)'
from k group by 姓名
exec(@s+'from k group by 科目')


应用SQL交叉表实现行列转换

--数据结构

ID

int

4

0

Grade

varchar

50

1

ExamYear

varchar

50

1

Name

varchar

50

1

Subject

varchar

50

1

Score

int

4

1

--数据体

ID

Grade

ExamYear

Name

Subject

Score

1.

2004级2班

2004

李明

数学

100

2.

2004级2班

2004

王强

数学

90

3.

2004级2班

2004

付超

数学

85

4.

2004级2班

2004

李明

语文

75

5.

2004级2班

2004

王强

语文

89

6.

2004级2班

2004

付超

化学

89

7.

2004级2班

2004

李明

化学

45

8.

2004级2班

2004

王强

化学

78

9.

2004级2班

2005

李明

数学

89

10.

2004级2班

2005

王强

数学

88

11.

2004级2班

2005

付超

数学

86

12.

2004级2班

2005

李明

语文

78

13.

2004级2班

2005

王强

语文

92

14.

2004级2班

2005

付超

化学

94

15.

2004级2班

2005

付超

语文

59

16.

2004级2班

2005

李明

化学

54

17.

2004级2班

2005

王强

化学

80

--SQL语句

Declare@SqlStrnvarchar(2000)

--构建Sql语句,生成2004级2班 2004年的考虑成绩表

Select@SqlStr='selectGrade,ExamYear,Name,'

--生成条件选择语句,使用Distinct把所有科目全部列出,当然,可以加上条件,如:仅某一年度的考试科目

Select@SqlStr=@SqlStr+'SUM(CASESubjectWHEN'''+Subject+'''THENScoreELSE0END)AS'''+Subject+''','from(SelectDistinctSubjectfromExamResultwhereExamYear=2004)AsTemTable

--补全Sql语句,并使用GroupBy对重复的记录进行汇总

Select@SqlStr=left(@SqlStr,Len(@SqlStr)-1)+'fromExamResultwhereExamYear=2004GroupByName,Grade,ExamYear'

--执行Sql

Exec(@SqlStr)

Go

--执行结果

Grade ExamYear Name 化学 数学 语文
1 2004级2班 2004 付超 89 85 56
2 2004级2班 2004 李明 45 100 75
3 2004级2班 2004 王强 78 90 89


行列转换例子

一、現有一個表TB1,其字段如下:(Name:代表姓名,Province:代表省份,Score:代表業務顧客數量)
Name  Province Score
李三  四川     5
小王  四川     3
小張  廣州     3
李三  廣州     2
小張  湖南     3
李三  湖南     4

得到下面的結果:
姓名  四川  廣州  湖南  總計
李三  5     2     4     11
小王  3     0     0     3
小張  0     3     3     6

注意:省份必須根據TB1表中所有出現的省份進行統計

create table A
(
  Name varchar(10),
  Province varchar(20),
  Score int
)
insert A
select '李三','四川',5 union
select '小王','四川',3 union
select '小張','廣州',3 union
select '李三','廣州',2 union
select '小張','湖南',3 union
select '李三','湖南',4

--测试
declare @s varchar(8000)
set @s = ''

select @s = @s +','+Province+'= sum(case province when'''+province+'''then score else 0 end)'
from A group by Province order by Province

exec ('select name '+@s+',sum(Score) As Total from A group by Name order by Name')

--测试结果
--   Name  广州    湖南    四川     Total
-- 1 李三24511
-- 2 小王0033
-- 3 小張3306

--测试结束
drop table A

二、这是邹建写的一个交叉表的实例
--测试数据
CREATE TABLE #XS_REP_CLIENTPROD_CHX
(
 C_PTID varchar (16) NULL ,
 C_PTNAME varchar(80)  NULL,
 c_PCID varchar(50)  NULL,
 C_CUSTID varchar (15)  NULL ,
 c_CustName varchar (100) NULL ,
-- N_PRICE  numeric(18, 2) NULL ,
-- N_PRENOINVOICE numeric(18, 3) NULL ,
 N_SALEWEIGHT numeric(18, 3) NULL --,
-- N_INVOICEWEIGHT numeric(18, 3) NULL ,
-- N_NOINVOICE numeric(18, 3) NULL,
-- N_PRENOINVOICE_m  numeric(18, 3) NULL,
-- N_SALEWEIGHT_m numeric(18, 3) NULL ,
-- N_INVOICEWEIGHT_m numeric(18, 3) NULL ,
-- N_NOINVOICE_m numeric(18, 3) NULL
)

insert #XS_REP_CLIENTPROD_CHX
          select '001001','葡萄','0201','0201001','客户1',1
union all select '001001','葡萄','0201','0201002','客户2',2
union all select '001001','苹果','0201','0201001','客户1',3
union all select '001001','苹果','0201','0201002','客户2',4
go

--查询
declare @s varchar(8000)
set @s=''
select @s=@s+',['+C_PTNAME+']=sum(case C_PTNAME when '''
 +C_PTNAME+''' then N_SALEWEIGHT else 0 end)'
from #XS_REP_CLIENTPROD_CHX
group by C_PTNAME
exec('
select c_PCID=case
  when grouping(c_PCID)=1 then ''总计''
  else c_PCID end
 ,C_CUSTID=case
  when grouping(c_PCID)=1 then ''''
  when grouping(C_CUSTID)=1 then ''小计''
  else C_CUSTID end
 ,c_CustName=case
  when grouping(c_CustName)=0 then c_CustName
  else '''' end
 '+@s+'
from #XS_REP_CLIENTPROD_CHX
group by c_PCID,C_CUSTID,c_CustName with rollup
having (grouping(c_PCID)=1 or grouping(C_CUSTID)=1)
 or  grouping(c_CustName)=0
')
go

--删除测试
drop table #XS_REP_CLIENTPROD_CHX

/*--测试结果

c_PCID     C_CUSTID        c_CustName           苹果         葡萄    
---------- --------------- -------------------- ----------- ---------
0201       0201001         客户1                  3.000      1.000
0201       0201002         客户2                  4.000      2.000
0201       小计                                   7.000      3.000
总计                                              7.000      3.000

--*/

三 行列数

create table fbill(fauxqty int,Fdeptidname varchar(20),fsupplyidname varchar(20))
insert into fbill select 50,'信息部','十里庙  '
insert into fbill select 20,'业务部','经济开发'
insert into fbill select 20,'销售部','十里庙  '
insert into fbill select 1 ,'信息部','十里庙  '
insert into fbill select 2 ,'信息部','经济开发'
insert into fbill select 30,'业务部','经济开发'
insert into fbill select 5 ,'业务部','经济开发'
insert into fbill select 6 ,'业务部','经济开发'
go

declare @sql varchar(8000)
set @sql=''

select @sql=@sql+','+Fdeptidname+'=sum(case Fdeptidname when '''+Fdeptidname+''' then fauxqty else 0 end)'
from fbill group by Fdeptidname

set @sql='select  fsupplyidname as 客户'+@sql+' from fbill group by fsupplyidname'
exec(@sql)
go

/*
客户                   销售部         信息部         业务部        
-------------------- ----------- ----------- -----------
经济开发                 0           2           61
十里庙                  20          51          0
*/

drop table fbill
go


经常用到的交叉表问题,一般用动态SQL能生成动态列!

--原贴

http://community.csdn.net/Expert/topic/4200/4200386.xml?temp=.4856989

原始表如下格式:
Class     CallDate    CallCount
1     2005-8-8    40
1     2005-8-7    6
2     2005-8-8    77
3     2005-8-9    33
3     2005-8-8    9
3     2005-8-7    21

根据Class的值,按日期分别统计出CallCount1,CallCount2,CallCount3。
当该日期无记录时值为0
要求合并成如下格式:
CallDate  CallCount1  CallCount2  CallCount3
2005-8-9  0       0       33
2005-8-8  40      77      9
2005-8-7  6       0       21

--创建测试环境
Create table  T  (Class varchar(2),CallDate datetime, CallCount int)
insert into T select '1','2005-8-8',40
union all select '1','2005-8-7',6
union all select '2','2005-8-8',77
union all select '3','2005-8-9',33
union all select '3','2005-8-8',9
union all select '3','2005-8-7',21
--动态SQL
declare @s varchar(8000)
set @s='select CallDate '
select @s=@s+',[CallCount'+Class+']=sum(case when Class='''+Class+''' then CallCount else 0 end)'
from T
group by Class
set @s=@s+' from T group by CallDate order by CallDate desc '
exec(@s)

--结果

CallDate                                               CallCount1  CallCount2  CallCount3 
------------------------------------------------------ ----------- ----------- -----------
2005-08-09 00:00:00.000                                0           0           33
2005-08-08 00:00:00.000                                40          77          9
2005-08-07 00:00:00.000                                6           0           21

--删除测试环境

drop table T


详细介绍SQL交叉表的实例

  很简单的一个东西,见网上好多朋友问“怎么实现交叉表?”,以下是我写的一个例子,数据库基于SQL SERVER 2000。

  交叉表实例

  建表:

  在查询分析器里运行:

  CREATE TABLE [Test] (

  [id] [int] IDENTITY (1, 1) NOT NULL ,

  [name] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,

  [subject] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,

  [Source] [numeric](18, 0) NULL

  ) ON [PRIMARY]

  GO

  INSERT INTO [test] ([name],[subject],[Source]) values (N'张三',N'语文',60)

  INSERT INTO [test] ([name],[subject],[Source]) values (N'李四',N'数学',70)

  INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'英语',80)

  INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'数学',75)

  INSERT INTO [test] ([name],[subject],[Source]) values (N'王五',N'语文',57)

  INSERT INTO [test] ([name],[subject],[Source]) values (N'李四',N'语文',80)

  INSERT INTO [test] ([name],[subject],[Source]) values (N'张三',N'英语',100)

  Go

  

  交叉表语句的实现:

  用于:交叉表的列数是确定的

  select name,sum(case subject when '数学' then source else 0 end) as '数学',

  sum(case subject when '英语' then source else 0 end) as '英语',

  sum(case subject when '语文' then source else 0 end) as '语文'

  from test

  group by name

  --用于:交叉表的列数是不确定的

  declare @sql varchar(8000)

  set @sql = 'select name,'

  select @sql = @sql + 'sum(case subject when '''+subject+'''

  then source else 0 end) as '''+subject+''','

  from (select distinct subject from test) as a

  select @sql = left(@sql,len(@sql)-1) + ' from test group by name'

  exec(@sql)

  go

  运行结果:

  

SqlServer生成交叉表大全相关推荐

  1. 如何生成表_SPSS简单操作 | 如何生成交叉表?

    (。・∀・)嗨!学堂君,今天讲什么内容呢? 今天要分享的是如何生成交叉表. 什么是交叉表呀? 如果说交叉表可能大家会比较陌生,但是说到列联表可能就会比较熟悉.交叉表是我们在操作SPSS进行列联表分析时 ...

  2. 生成交叉表的简单通用存储过程

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_qry]') and OBJECTPROPERTY(id ...

  3. mysql 交叉表 存储过程_用于生成交叉表的存储过程的存储过程

    以前总是在网上搜一些交叉表生成的相关代码 但是使用起来总是很复杂 看看 刚出炉的东西对你来说是不是有所帮助 :_) 先看看下一个生成的存储过程 :SQLServer2000 Create Proced ...

  4. Python+pandas使用交叉表分析超市营业额数据

    交叉表是一种特殊的透视表,往往用来统计频次,也可以使用参数aggfunc指定聚合函数实现其他功能.扩展库pandas提供了crosstab()函数用来生成交叉表,返回新的DataFrame,其语法为: ...

  5. 在MySQL中实现交叉表查询1(静态交叉表)

    在MySQL中实现交叉表查询1(静态交叉表) 一.什么是交叉表 交叉表查询是将来源于某个表中的字段进行分组,一组列在交叉表左侧,一组列在交叉表上部,并在交叉表行与列交叉处显示表中某个字段的各种计算值. ...

  6. 【Pandas分组聚合】进阶:透视表、交叉表(pivot_table() 、crosstab())

    Pandas透视表.交叉表 创建DataFrame结构 透视表 pivot_table() 单列聚合 多列聚合 交叉表 crosstab() 计算分组频率 两列分组后求第三列的统计指标 创建DataF ...

  7. 超市销售数据分析python、求某一个人的营业额总和_Python+pandas使用交叉表分析超市营业额数据!这超市怕是!...

    交叉表是一种特殊的透视表,往往用来统计频次,也可以使用参数aggfunc指定聚合函数实现其他功能.扩展库pandas提供了crosstab()函数用来生成交叉表,返回新的DataFrame,其语法为: ...

  8. 一维表和交叉表的转化

    一维表转化为交叉表 通过制作数据透视表,合理分布行和列的内容,生成交叉表. (1)原始表 (2)生成透视表,设置字段显示形式 (3)透视表结果如下: (4)交叉表结果为: 交叉表转化为一维表 (1)原 ...

  9. 数据库系统原理与应用教程(052)—— MySQL 的数据完整性(十四):交叉表查询(行列转换)

    数据库系统原理与应用教程(052)-- MySQL 的数据完整性(十四):交叉表查询(行列转换) 目录 数据库系统原理与应用教程(052)-- MySQL 的数据完整性(十四):交叉表查询(行列转换) ...

最新文章

  1. Go 学习笔记(15)— 函数(01)[函数定义、函数特点、多值返回、实参形参、变长参数,函数作为参数调用]
  2. [翻译]一步步教你配置SQL SERVER合并复制(五)配置Publisher(上)
  3. 【PAT乙级】1043 输出PATest (20 分)
  4. zuul路由前缀配置
  5. php输出0到5之间到数,php如何实现输出链表倒数第k个结点(代码实例)
  6. HDU 2647 Reward (拓扑排序)
  7. 上采样,下采样,过采样,欠采样的区别
  8. Spring中资源的加载ResourceLoader
  9. 图形化安装配置:安装oracle、新建数据库、用plsql连接oracle,套路明白了其实挺简单...
  10. while/for 嵌套expect 批量免密码传文件
  11. 地理空间数据云 如何预约下载数据 Landsat8
  12. keep-alive用法(include、exclude、max)
  13. win10分辨率设置正确但屏幕却被拉伸了,如何处理
  14. 深入浅出MySQL规范
  15. 笔记本设置WiFi热点命令操作
  16. 设计模式(一)设计模式的分类与区别
  17. Postgresql逻辑复制报错could not start WAL streaming: ERROR: replication slot “x“is active for PID xxx
  18. 硬件测试工程师的待遇和前景
  19. GHOST使用教程(图解)
  20. 爬取百度翻译中得到sign值

热门文章

  1. Hadoop流程---从tpch到hive
  2. 基于ROS的qbo机器人
  3. IntelliJ IDEA 注册码(phpstorm等IDE)
  4. mmclassification
  5. 计算机视觉 目标分割
  6. 国内股票KDJ指标计算,Python实现KDJ指标计算,Talib实现KDJ指标计算
  7. 软件项目开发流程及人员职责
  8. java笔试题含答案总结五
  9. 机器学习之LSI:文本主题模型之潜在语义分析(LSI)
  10. 数据库原理与应用--数据库系统概述