`
jonakang
  • 浏览: 4064 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

oracle9i单表分组问题,有点搞人!

阅读更多
Database: Oracle9iU2
有这么个表:employee
id,name,birthday,duty,degree,title,degree_title
报表格式如图:
  • 大小: 73.8 KB
分享到:
评论
35 楼 tommy402 2008-09-10  
可以这样,把同一个表起不同的别名,和你的列个数一样,然后where中的条件都有一样的,即:
select a.id,b.name,c.birthday from employee a,employee b,employee c
where X and Y and Z;

X、Y、Z是同一个where条件,用不同的别名代替就可以
34 楼 anweixiao 2008-04-11  
这种问题我觉得比较好的做法是先统计出行数据需要的信息,然后分行得到统计数据的结果比较好
33 楼 Ben.Sin 2008-04-10  
可以考虑这样做
select sum(decode(t1.degree_title, '初级', 1, 0) n,
       sum(decode(t1.duty,'管理人员', 1, 0)) o
from t1

或者用case when方式代替decode
32 楼 jewels007 2008-04-09  
    可以考虑用临时表,先把人员按人员类别insert到某张表,当然可以是临时表。表定义就是人员类别和人员代码。然后用人员类别(管理人员等)来循环。当循环到某种类别的人(比如是管理人员)时,再对临时表中符合条件的人员进行统计,再插入到另一张临时表当中。这样人员条件只要写一次,而且比较清楚。我们对多单位多种信息人数的汇总还有金额的汇总就是用这个方法。当然这就不光光是语句了,要用存储过程了。大体思路是这样,具体表设计当然还要看你的具体要求。
31 楼 luxiaoan 2008-04-07  
附上存储过程,仅供参靠

CREATE proc LoadFB(@cDateStr varchar(100) ,@cDepartment varchar(100),@cGoodsName varchar(100),@siKind Char(10))
as
begin

declare @MainSQL varchar(1000)
declare @CASESQl nvarchar(4000)
declare @VerItemName varchar(50)
declare @uppSQl  varchar(1000)
declare @lastItems varchar(500)
declare @itemN int

-- 汇总
set @MainSQL = '   FROM (SELECT cGoodName, SUM(fQuantity) AS ITEM0 ,cDepartment
FROM (SELECT TVerVatCheck.cGoodName, TVerVatItem.fQuantity,
              TVerVatCheck.dVerifyDate, TVerVatItem.cDepartment
        FROM TVerVatCheck WITH (NOLOCK) INNER JOIN
              TVerVatItem WITH (NOLOCK) ON
              TVerVatCheck.iVerVatCheckSn = TVerVatItem.iVerVatCheckSn INNER JOIN
             TVerItem ON TVerVatItem.siVerItemSn = TVerItem.siVerItemSn
        WHERE (TVerItem.siKind = '+@siKind+') AND (TVerItem.siGoodCheck = 1)    '+@cDateStr+'
  '+@cDepartment+'    '+@cGoodsName+'
) A GROUP BY cGoodName,cDepartment ) A   '


--明晰

declare @addSQl   varchar(2000) 
   set @addSQl = '  FROM (SELECT cGoodName, SUM(fQuantity) AS fTotD, cVerItemName,cDepartment
FROM (SELECT TVerVatCheck.cGoodName, TVerVatItem.fQuantity,
              TVerItem.cVerItemName, TVerVatCheck.dVerifyDate,
              TVerVatItem.cDepartment
        FROM TVerVatCheck WITH (NOLOCK) INNER JOIN
              TVerVatItem WITH (NOLOCK) ON
              TVerVatCheck.iVerVatCheckSn = TVerVatItem.iVerVatCheckSn INNER JOIN
              TVerItem ON TVerVatItem.siVerItemSn = TVerItem.siVerItemSn
where  (TVerItem.siKind ='+@siKind+') AND (TVerItem.siGoodCheck = 1)  and  1=1  '+@cDateStr+'   '+@cDepartment+'  ) S
GROUP BY cGoodName, cVerItemName,cDepartment) A  '



declare curItem cursor for
select cVerItemName from TVerItem  where siKind = @siKind and siGoodCheck = 1 ORDER BY siVerItemSn

open curItem
set @itemN = 0
set @CASESQl = ''
set @uppSQl = ''
set @lastItems = 'ITEM0'
fetch next from curItem into @VerItemName
while @@fetch_status = 0
begin
   set @itemN = @itemN +1
   if(@itemN = 1)
   begin
       set @CASESQl  = @CASESQl + ' , CASE WHEN cVerItemName ='+char(39)+ @VerItemName+char(39)+'  THEN fTotD ELSE 0 END AS ITEM'+Cast(@itemN As varchar(3))
       set @uppSQl = @uppSQl +', SUM(ITEM'+Cast(@itemN As varchar(3))+') as ITEM'+Cast(@itemN As varchar(3))
    end
    else
    begin
       set @CASESQl  = @CASESQl + ' ,CASE WHEN cVerItemName ='+ char(39)+@VerItemName+char(39)+'  THEN fTotD ELSE 0 END AS ITEM'+Cast(@itemN As varchar(3))
       set @uppSQl = @uppSQl +', SUM(ITEM'+Cast(@itemN As varchar(3))+') as ITEM'+Cast(@itemN As varchar(3))
    end
    set @lastItems = @lastItems+',ITEM'+Cast(@itemN As varchar(3))
   fetch next from curItem into @VerItemName
end

close curItem
deallocate curItem

--drop table #tmpTable
--print @CASESQl
set @CASESQl = 'SELECT cGoodName  '+@CASESQl+@addSQl

set @CASESQl = 'select cGoodName      '+@uppSQl + '   FROM ( '+ @CASESQl+') B  GROUP By cGoodName '

set @CASESQl  = ' select A.cGoodName, cDepartment, '+@lastItems+@MainSQL+ 'LEFT OUTER JOIN  ( '+@CASESQl+' ) B ON A.cGoodName = B.cGoodName ' 

set @CASESQl = 'select cGoodName,cDepartment,' +@lastItems +' FROM ( '+ @CASESQl+ ') C ORDER BY cGoodName '

--print @CASESQl


exec sp_executesql @CASESQl
end

--set @itemN= 0  exec LoadFB   

--while @itemN < 125
--begin
--  set @itemN = @itemN + 1   
--  print char(@itemN)+':'+cast(@itemN as varchar(3))
--end

GO

30 楼 luxiaoan 2008-04-07  
根据实际的开发实践,当表中的记录小于20万时  用这种方法做是比较有效率的
而且如果是动态的二维表的话 ,这种做法应该是首选了(就要用存储过程动态生成所要的sql语句在执行)
29 楼 daydayup 2008-04-03  
luxiaoan 的思路是对的,sql没仔细看,
To angeltping,
用这种吐血的SQL,应该比多连几次数据库要快得多吧
28 楼 applefeng_52 2008-03-26  
一条sql语句就可以,用split来分隔语句
27 楼 angeltping 2008-03-25  
这种吐血sql不要用。
可以用尽量简单的多个sql返回数据。在程序里组装数据机构。
这种性能的大部分开销是执行sql。在程序中花费的时间不会太多
26 楼 luxiaoan 2008-03-24  
select * from ( select count(*),duty from employee with (nolock)group by duty ) A left outer join (
select duty,sum(birthday1) as birthday1 ,sum(birthday1) as birthday1 ,sum(birthday1) as birthday1 from ( select case when getdate()-birthday)
<=35 then 1 else 0 end as birthday1,case when getdate()-birthday >35 and getdate()-birthday <=55 then 1 else 0 end as birthday2 ,case when
getdate()-birthday) > 55 then 1 else 0 end as birthday3,duty from  employee ) tbirthday group by duty ) B  on a.duty = b.duty
left outer join (select sum(ibs) as ibs .... ,duty from (  select case when degree = '博士' when 1 else 0 end as ibs.... from  employee )
tuty group by )  c duty on a.duty = c.duty  ..其他2个 title,degree_title
25 楼 luxiaoan 2008-03-24  
24 楼 rabbitbug 2008-03-24  
找找中间产品
或是干脆一项项算好再填上去
当然这样维护性差了
23 楼 meikefu 2008-03-19  
javaTo 写道
为什么非要在查询语句中费那么大劲呢!你这种sql,如果并发量稍大一点,造成死锁的几率就会很高。
给你说说我们的方案,一句简单的sql把需要的数据查出来,在程序中予以分类或计算,然后写入报表,如果对并发有要求,那么就来他几个线程

oracle查询是没有锁的,除非你用for update
22 楼 demo_yang 2008-03-18  
使用decode
count(null)是不计数的,即count(decode(...))
21 楼 gaoran2008 2008-03-15  
jonakang 写道
把它拆成N个简单的sql,问题基本上解决了-_-!

----------------------------------------------------------------------

这样的报表我做过了,呵呵。当时也是也楼主一样的去解决。可是在性能并不是很理想的。
后来想到一个办法:
    建立一个快照,你把你的每个数值的点的SQL语句,都写到快照里面去。每天晚上或者凌晨更新,最后的报表查询基于这张快照来查询。这个报表不是很复杂,应该没什么问题。
    如果要时时的数据,可以通过提出出业务的数据写function,然后你要去建立视图,不过SQL语句要优化。
20 楼 lumi 2008-03-14  
这是典型的中国式报表(复杂表头,不定列,数据跨行等)

个人认为sql语言的窗口函数+行列转换是个比较好的方案,不过写的sql比较多,但是效率绝对不差!

我不建议把sql写到程序里,整个存储过程吧,嘿嘿!

楼主如果乐意讨论,把表结构和数据贴出来大家讨论!
19 楼 jonakang 2008-03-14  
javaTo 写道
为什么非要在查询语句中费那么大劲呢!你这种sql,如果并发量稍大一点,造成死锁的几率就会很高。
给你说说我们的方案,一句简单的sql把需要的数据查出来,在程序中予以分类或计算,然后写入报表,如果对并发有要求,那么就来他几个线程

现在我采用的是这个方法,目前暂时没有考虑线程问题。
18 楼 jonakang 2008-03-14  
首先,谢谢大家的关注。
这里我大概的说下我遇到的问题:在一家企业内,我们对人力资源进行分类(管理人员,专业技术人员,生产技能人员,其他人员),这个分类被存放在一个基础数据表中(命名为BasicDataMaster=存放该分类的代码,BasicDataDetail=存放该代码对应的明细,如上述中的人员类别),在职员表中有个Field与之对应(并非关联,而是在做insert employee的时候把相应的类型存放在该字段中,只是个value)。与此同时,还有其他的企业内基础数据对employee进行描述,比如职称,学历,年龄(birthday),技术等级等等。报表要求如图所示。
17 楼 pig345 2008-03-13  
窗口函数,似乎是解决此类问题的东西。(听说而已,给您提个醒)
16 楼 lumi 2008-03-10  
楼主的方案太复杂了!

19个表连接,数据库会崩溃的!

用行转列,应该只要4个表的连接!

相关推荐

    Oracle 9i Client (Oracle 9i 客户端) 简化版 (不安装Oracle客户端,也可以使用PLSQL Developer)

    Oracle 9i Client (Oracle 9i 客户端) 简化版 (不安装Oracle客户端,也可以使用PLSQL Developer 不用安装Oracle客户端也可以使用PLSQL Developer 绿色! 安全! 轻便! 可靠! 1、本软件可作为简单的Oracle9i客户端...

    oracle 9i 全部下载链接

    根据提供的标题、描述、标签及部分内容,我们可以整理出关于Oracle 9i的多个关键知识点,主要包括不同操作系统下的版本、下载链接以及如何获取这些资源的方法。 ### Oracle 9i概述 Oracle 9i 是甲骨文公司(Oracle ...

    Oracle9i客户端精简版

    Oracle9i客户端精简版。 Oracle9i客户端精简版Oracle9i客户端精简版Oracle9i客户端精简版Oracle9i客户端精简版Oracle9i客户端精简版Oracle9i客户端精简版Oracle9i客户端精简版

    oracle9i经典测试用表

    该测试用表为Oracle9i的一个经典测试用表,雇员表;该表可以用来进行对数据库的增删查改的联系操作;请在MySQL中使用"SOURCE /路径"的方式进行使用

    oracle9i客户端精简版.zip

    Oracle 9i客户端精简版是一款专为数据库测试和数据检查设计的应用,它提供了一个轻量级的解决方案,便于快速安装和使用。这个版本优化了内存占用,节省了磁盘空间,使得用户能够迅速地进行数据库连接、查看表结构...

    oracle9i310.rar

    Oracle 9i是一款历史悠久但依然具有重要价值的关系型数据库管理系统,尤其对于初学者而言,它提供了深入了解数据库原理和操作的良好平台。"oracle9i310.rar" 是一个压缩包,其中包含了Oracle 9i的简化客户端版本,...

    windows server 2003 Oracle9i 安装

    Windows Server 2003 Oracle9i 安装指南 Windows Server 2003 是微软公司推出的服务器操作系统,而 Oracle9i 是 Oracle 公司推出的关系数据库管理系统。本文档将指导读者在 Windows Server 2003 上安装 Oracle9i ...

    wxh ORACLE9I删表空间问题

    ORACLE9I删表空间问题

    Oracle 9i 参考手册

    "游侠下载站使用说明.txt"可能是对获取和安装Oracle 9i的辅助指南,而"Oracle(CHM)"可能是一个包含Oracle 9i详细技术文档的离线帮助文件,用户可以通过查阅这个文件来学习和解决具体问题。 总的来说,Oracle 9i参考...

    oracle9i全备份导入到11g说明

    当将Oracle 9i的数据全备份导入到Oracle 11g版本时,经常会遇到由于`db_block_size`参数不一致导致的导入失败问题。这种情况下,如果直接进行导入操作,很可能会出现如下的错误提示:“ORA-02236: invalid filename...

    oracle9i教程

    Oracle9i基于SQL语言,其数据库概念包括实体(如表、视图)、数据类型(如数值、字符串、日期等)、索引、约束(如唯一性、非空约束)等。中英文对照的《Conceptes.chm》文件提供了详细的数据库概念解释,便于学习者...

    oracle9i的EXP和IMP

    Oracle 9i数据库系统是Oracle公司的一个重要版本,它提供了许多功能来支持数据管理,其中包括数据导入(IMP)和导出(EXP)工具。这两个工具是数据库管理员进行数据迁移、备份和恢复操作的关键组件。 **EXP(Export...

    oracle9i物理结构,oracle9i物理结构

    除了上述核心组件,Oracle 9i 物理结构还包括其他重要部分,如表空间(Tablespaces)和段(Segments),它们是逻辑结构与物理存储之间的桥梁。表空间由一个或多个数据文件组成,是数据库对象的逻辑容器,而段则代表...

    oracle9i下载地址

    oracle9i下载地址, 分三个IOS文件, 加压即可安装.

    Oracle9i 数据库安装

    Oracle9i 数据库安装是一个复杂的过程,涉及到多个步骤和配置选项。在开始安装之前,确保你的操作系统和硬件环境满足Oracle9i的要求。在这个例子中,操作系统是SuSE Linux 7.2,已经安装了Oracle9i Enterprise ...

    oracle9i客户端精简免安装.rar

    Oracle 9i是一款历史悠久的关系型数据库管理系统,由甲骨文公司(Oracle Corporation)开发,它在2001年发布,提供了许多先进的特性和功能,为企业的数据存储和管理提供了强大的支持。本压缩包“oracle9i客户端精简...

    oracle10g数据导入到oracle9i解决方案

    由于Oracle 9i与Oracle 10g之间存在版本差异,这可能涉及到一些兼容性问题,特别是当导出的数据包含BLOB、CLOB等大数据类型字段时。本文旨在提供一种解决方案来解决这一问题。 #### 问题描述 Oracle 9.2.0.5之前的...

    Oracle 9i初学者指南

    Oracle 9i初学者指南是一本专为对数据库管理感兴趣的初学者设计的教程,它涵盖了Oracle 9i数据库系统的基础知识、安装配置、管理和维护等多个重要方面。Oracle 9i是Oracle公司推出的一个重要版本,引入了许多创新...

    Oracle9i中文版基础培训教程

    本教程“Oracle9i中文版基础培训教程”由赵松涛制作,旨在帮助初学者掌握Oracle 9i的基本操作和概念,对于那些从其他数据库系统(如MySQL)转而学习Oracle的人来说,这是一个宝贵的资源。 Oracle数据库系统的核心...

    Oracle9i+Windows下安装

    百度云盘下载地址https://pan.baidu.com/s/1iU5zzuVbm2-uJtzQGr98zw windows下安装Oracle9i

Global site tag (gtag.js) - Google Analytics