oracle - 作报表需要的一些sql

作报表需要的一些oracle sql

天寒地冻,呆在家里又读完了《Mastering Oracle SQL》2nd,发现Oracle的功能还是很强悍,光函数就有两百个,那些面向对象的查询语言很难模拟,特别是SQL2003里针对OLAP的windows function等。
    幸好Hibernate3.0也支持SQL了。

1.报表合计专用的Rollup函数

销售报表
  广州     1月      2000元
  广州     2月      2500元
  广州                 4500元
  深圳     1月      1000元
  深圳     2月      2000元
  深圳                 3000元
  所有地区         7500元

以往的查询SQL:
Select  area,month,sum(money) from SaleOrder group by area,month
然后广州,深圳的合计和所有地区合计都需要在程序里自行累计

1.其实可以使用如下SQL:

   Select area,month,sum(total_sale) from SaleOrder group by rollup(area,month)

就能产生和报表一模一样的纪录

2.如果year不想累加,可以写成

   Select year,month,area,sum(total_sale) from SaleOrder group by year, rollup(month,area)

另外Oracle 9i还支持如下语法:

   Select year,month,area,sum(total_sale) from SaleOrder group by rollup((year,month),area)

3.如果使用Cube(area,month)而不是RollUp(area,month),除了获得每个地区的合计之外,还将获得每个月份的合计,在报表最后显示。

4.Grouping让合计列更好读
  RollUp在显示广州合计时,月份列为NULL,但更好的做法应该是显示为"所有月份"
  Grouping就是用来判断当前Column是否是一个合计列,1为yes,然后用Decode把它转为"所有月份"

  Select  Decode(Grouping(area),1,‘所有地区‘,area) area,
          Decode(Grouping(month),1,‘所有月份‘,month),
          sum(money)
  From SaleOrder 
  Group by RollUp(area,month);

2.对多级层次查询的start with.....connect by
   比如人员组织,产品类别,Oracle提供了很经典的方法

 SELECT LEVEL, name, emp_id,manager_emp_id
 FROM employee
 START WITH manager_emp_id is null
 CONNECT BY PRIOR emp_id = manager_emp_id;

上面的语句demo了全部的应用,start with指明从哪里开始遍历树,如果从根开始,那么它的manager应该是Null,如果从某个职员开始,可以写成emp_id=‘11‘
CONNECT BY 就是指明父子关系,注意PRIOR位置
另外还有一个LEVEL列,显示节点的层次

3.更多报表/分析决策功能
3.1 分析功能的基本结构
     分析功能() over( partion子句,order by子句,窗口子句)
     概念上很难讲清楚,还是用例子说话比较好.

3.2 Row_Number 和 Rank, DENSE_Rank
    用于选出Top 3 sales这样的报表
    当两个业务员可能有相同业绩时,就要使用Rank和Dense_Rank
    比如
              金额    RowNum  Rank  Dense_Rank
    张三 4000元    1             1        1
    李四 3000元    2             2        2
    钱五 2000元    3             3        3
    孙六 2000元    4             3        3
    丁七 1000元    5             5        4

这时,应该把并列第三的钱五和孙六都选进去,所以用Ranking功能比RowNumber保险.至于Desnse还是Ranking就看具体情况了。

    SELECT salesperson_id, SUM(tot_sales) sp_sales,
    RANK( ) OVER (ORDER BY SUM(tot_sales) DESC) sales_rank
    FROM orders
    GROUP BY salesperson_id

3.3 NTILE 把纪录平分成甲乙丙丁四等
        比如我想取得前25%的纪录,或者把25%的纪录当作同一个level平等对待,把另25%当作另一个Level平等对待

    SELECT cust_nbr, SUM(tot_sales) cust_sales,
    NTILE(4) OVER (ORDER BY SUM(tot_sales) DESC) sales_quartile
    FROM orders
    GROUP BY cust_nbr
    ORDER BY 3,2 DESC;

NTITLE(4)把纪录以 SUM(tot_sales)排序分成4份.

3.4 辅助分析列和Windows Function
     报表除了基本事实数据外,总希望旁边多些全年总销量,到目前为止的累计销量,前后三个月的平均销量这样的列来参考.
    这种前后三个月的平均和到目前为止的累计销量就叫windows function,是SQL2003的针对OLAP的新函数, 见下例

    SELECT month, SUM(tot_sales) monthly_sales,
           SUM(SUM(tot_sales)) OVER (ORDER BY month
           ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) max_preceeding
    FROM orders
    GROUP BY month
    ORDER BY month;
    SELECT month, SUM(tot_sales) monthly_sales,
           AVG(SUM(tot_sales)) OVER (ORDER BY month
           ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) rolling_avg  
    FROM orders
    GROUP BY month
    ORDER BY month;

Windows Function的关键就是Windows子句的几个取值
    1 PRECEDING 之前的一条记录
    1 FOLLOWING 之后的一条记录
    UNBOUNDED PRECEDING 之前的所有记录
    CURRENT ROW 当前纪录

4.SubQuery总结
  SubQuery天天用了,理论上总结一下.SubQuery 分三种
  1.Noncorrelated 子查询   最普通的样式.
  2.Correlated Subqueries  把父查询的列拉到子查询里面去,头一回cyt教我的时候理解了半天.
  3.Inline View                           也被当成最普通的样式用了.

然后Noncorrelated 子查询又有三种情况
  1.返回一行一列    where price < (select max(price) from goods )
  2.返回多行一列    where price>= ALL (select price from goods where type=2)
                          or where NOT price< ANY(select price from goods where type=2)
                              最常用的IN其实就是=ANY()
  3.返回多行多列    一次返回多列当然就节省了查询时间

          UPDATE monthly_orders 
          SET (tot_orders, max_order_amt) =
              (SELECT COUNT(*), MAX(sale_price)
          FROM cust_order)         
          DELETE FROM line_item
          WHERE (order_nbr, part_nbr) IN
                (SELECT order_nbr, part_nbr FROM cust_order c)
时间: 2025-01-01 06:40:31

oracle - 作报表需要的一些sql的相关文章

Oracle数据库--实用操作(3) PL/SQL

Oracle----PL/SQL PL/SQL 是过程语言(Procedural Language)与结构化查询语言(SQL)结合而成的编程语言 PL/SQL 是Oracle特有的,是对 SQL 的扩展.不同数据库厂商都有类似的"方言",提供的新特性. 支持多种数据类型,如大对象和集合类型,可使用条件和循环等控制结构 可用于创建存储过程.触发器和程序包,给SQL语句的执行添加程序逻辑 与Oracle 服务器和Oracle 工具紧密集成,具备可移植性.灵活性和安全性 PL/SQL 的优点

oracle入门(6)——PL/SQL常用语法

[本文介绍] 本文不是”语法大全“,只是记录下作项目里自己常用的一些语法.方便查询. [语法] [输出]   (1)输出语法 DBMS_OUTPUT.PUT_LINE( ) [定义]   (1)定义变量: ...... as 变量名 类型(长度) begin ...... 例如: (2)定义变量 ,类型 依赖其他变量的类型 例如: 这样,改了name的类型,returnValue类型也跟着改变. (3)自定义类型(类似C语言的结构体)每次只能拿一条数据,不然会的报错. 例如: (4)以“表”做为

Oracle EBS-SQL (SYS-8):职责定义明细.sql

SELECT DISTINCT fa.application_short_name 模块,                 b.responsibility_name 职责名称, fa.application_name 应用产品,                 b.responsibility_key 责任关键字, b.description 说明,                 DECODE (b.data_group_id, 0, '标准', '') 数据组,              

Oracle EBS-SQL (SYS-10):锁定表查询.sql

/*死锁查询-1*/ SELECT o.object_name, l.session_id,l.process, l.locked_mode FROM v$locked_object l , dba_objects o WHERE o.object_id=l.object_id ------------------------------------------------ /*死锁查询-2*/ select GL.SESSION_ID,         do.object_name,     

Oracle EBS-SQL (SYS-9):职责使用菜单.sql

select aa.menu_name, aa.user_menu_name, aa.type,                 aa.description, aa.ENTRY_SEQUENCE, aa.prompt,                 aa.sub_user_menu_name, aa.user_function_name,                 aa.description1 from ( SELECT DISTINCT fmv.menu_name, fmv.use

Oracle EBS-SQL (SYS-5):sys_配置文件查询.sql

select    distinct l.profile_option_name,             v.profile_option_value,             fu.user_nameform     applsys.fnd_profile_option_values v,            apps.fnd_profile_options_vl          l,            apps.fnd_user                           

Oracle 学习笔记 17 -- 异常处理(PL/SQL)

程序在执行过程中出现异常是正常的,在程序的编写过程中出现异常也是不可避免的.但是要有相应的异常处理的机 制,来保证程序的正常执行.PL/SQL程序执行过程中出现的错误,称为异常.一个优秀的程序都应该能够正确处理 各种出错的情况,并尽可能的从错误中恢复.PL/SQL提供了异常处理机制. 概念: 异常处理(exception)是用来处理正常执行过程中未预料的事件,程序块的异常处理定义的错误和自定义的错误, 由于PL/SQL程序块一旦产生异常而没有指出如何处理时,程序就会异常的终止. 有三种类型的错误

Oracle 如何写出高效的 SQL

转自:Oracle 如何写出高效的 SQL 要想写出高效的SQL 语句需要掌握一些基本原则,如果你违反了这些原则,一般情况下SQL 的性能将会很差. 1. 减少数据库访问次数连接数据库是非常耗时的,虽然应用程序会采用连接池技术,但与数据库交互依然很耗时,这就要求我们尽量用一条语句干完所有的事,尤其要避免把SQL 语句写在循环中,如果你遇到这样的人,应该毫不犹豫给他两个耳光. 2. 避免在有索引的字段上使用函数在索引字段上使用函数会使索引失效,我们可以通过其他方式避免使用函数,如:尽量 避免在 S

ORACLE PATCH 版本的查询 PL/SQL

--ORACLE PATCH 版本的查询 PL/SQL SELECT DD.PATCH_NAME,        PP.CREATION_DATE,        PP.DRIVER_FILE_NAME,        LANG.LANGUAGE  FROM AD_PATCH_DRIVERS PP,        AD_APPLIED_PATCHES DD,        AD_PATCH_DRIVER_LANGS LANG WHERE PP.APPLIED_PATCH_ID = DD.APPL