Office中国论坛/Access中国论坛

标题: 请问有人在ADP中做过动态交叉表吗?怎么做的呀? [打印本页]

作者: thezhehan1    时间: 2003-5-29 23:16
标题: 请问有人在ADP中做过动态交叉表吗?怎么做的呀?
即不能预先知道列数,依赖于输入参数的交叉表,就象ACCESS中那样.
作者: cg1    时间: 2003-5-30 04:41
adp已经不存在交叉表这个功能了,这个功能在Access中算是特色,t-sql却没有了。

你可参考sql的联机帮助,里面有有关如何建立和交叉表功能一致的t-sql存储过程。
作者: thezhehan1    时间: 2003-5-30 17:39
联机帮助中只介绍了静态的(即事先知道列数的)交叉表, 我想知道有没有办法实现动态的(即列数依赖于参数的)的交叉表.
至于有没有标准的PIVOT语句,或是用SQL-SERVER中的T-SQL模拟的都没有关系.
关键是:是否能够在APD中实现动态的交叉表功能!
作者: cg1    时间: 2003-6-2 22:51
应该可以实现,不过我到是没有具体研究过,这样说吧,如果用vba来操纵t-sql代码,不写存储过程的话可以做到。

但是我相信,用t-sql做动态的交叉表查询也肯定可以的,只是我没做过,你问问其他用adp的人看看


[此贴子已经被作者于2003-6-2 14:52:10编辑过]


作者: chm11    时间: 2005-3-11 21:50
复杂,抄一段别人写的参考。

仔细看一下,拿来用还是很简单,佩服作者!

SqlServer如何生成动态交叉表查询    fuxc(原作)  

首先检索列头信息,形成一个游标,然后遍历游标,将上面查询语句里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表里每个客户年度订单数量,大家可以运行试一下效果,虽然列头显示的名称不恰当,但基本效果出来了,相信大家通过对代码再作简单修改,可以达到满意的交叉表效果。

[此贴子已经被作者于2005-3-11 14:54:46编辑过]


作者: chm11    时间: 2005-3-11 21:53
简单的静态的

SqlServer如何生成动态交叉表查询    fuxc(原作)  

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

[此贴子已经被作者于2005-3-11 14:49:40编辑过]


作者: yodong    时间: 2005-3-12 21:49
真好!




欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) Powered by Discuz! X3.3