`
chun521521
  • 浏览: 281923 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

oracle 行列统计转换

 
阅读更多

纯粹自己使用方便;

本文系转载:http://www.cnblogs.com/fjfzhkb/archive/2007/11/30/978267.html

感谢网友提供!

 

体会:要用decode /group by/ order by/sign/sum来实现不同的统计和不同报表的生成

--求hkb_test1中Y的值既是1,也是3,也是5的X
select * from hkb_test1;
X        Y
---- -----
a        1
b        1
a        3
d        2
e        4
f        5
a        5
d        3
d        6
b        5
c        4
b        3

结果:
X
----
a
b
--方法一
select x
  from hkb_test1
 group by x
having sum(decode(y, 1, -1, 3, -1, 5, -1, 0)) = -3;

--方法二
select x
  from hkb_test1
 group by x
having(sign(sum(decode(y, 1, -1, 0))) + sign(sum(decode(y, 3, -1, 0))) + sign(sum(decode(y, 5, -1, 0))) <= -3);

PS:  
    sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1
所以可以用sign和decode来完成比较字段大小来区分某个字段。
select decode(sign(字段1-字段2),-1,字段3,字段4) from dual;

抄来的没有弄的很明白的:
  sign是一个对于写分析SQL有很强大的功能
  下面对sign进行一些总结:
  但属性student取0和1以外的值,或者student取两个以上的标法值,问题就不会这么简单了
  解决办法就是特征函数(abs(),sign())
  
  常用的特征算法
  [A=B]=1-abs(sign(A-B))
  [A!=B]=abs(sign(A-B))
  [A<B]=1-sign(1+sign(A-B)) 不能用-sign(A-B):因为如果不满足A  
    [A<=B]=sign(1-sign(A-B))
  [A>B]=1-sign(1-sign(A-B))
  [A>=B]=sign(1+sign(A-B)))
  [NOTα]=1-d[α]
  [αANDb ]=d[α]*d[b]
  [αOR b ]=sign(d[α]+d[b ])
  
  例如:
  A<B             Decode( Sign(A-B), -1, 1, 0 )
  A<=B            Decode( Sign(A-B), 1, 0, 1 )
  A>B             Decode( Sign(A-B), 1, 1, 0 )
  A>=B            Decode( Sign(A-B), -1, 0, 1 )
  A=B             Decode( A, B, 1, 0 )
  A between B and C        Decode( Sign(A-B), -1, 0, Decode(Sign(A-C), 1, 0, 1 ))
  A is null          Decode(A,null,1,0)
  A is not null        Decode(A,null,0,1)
    A in (B1,B2,...,Bn)        Decode(A,B1,1,B2,1,...,Bn,1,0)
  nor LogA          Decode( LogA, 0, 1, 0 )   
  LogA and LogB         LogA * LogB
  LogA or LogB         LogA + LogB
  LogA xor LogB         Decode(Sign(LogA),Sign(LogB),0,1)
 
  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
select * from grade1;
STUDENTID SUBJECTID MARK
--------- --------- ----
      101 A01         59
      101 A02         72
      101 A03         90
      102 A01         75
      102 A02         91
      103 A01         71

--统计学生参加的考试成绩
select STUDENTID,
       sum(decode(SUBJECTID,'A01', mark)) a,
       sum(decode(SUBJECTID,'A02', mark)) b,
       sum(decode(SUBJECTID,'A03', mark)) c
  from grade1
 group by STUDENTID;

STUDENTID          A          B          C
--------- ---------- ---------- ----------
      102         75         91
      101         59         72         90
      103         71           

--统计四种分数段的人数
select sum(case
             when mark < 60 then
              1
             else
              0
           end) as "not passed",
       sum(case
             when mark between 60 and 79 then
              1
             else
              0
           end) as "passed",
       sum(case
             when mark between 80 and 89 then
              1
             else
              0
           end) as "good",
       sum(case
             when mark >= 90 then
              1
             else
              0
           end) as "excellent"
  from grade1;
not passed     passed       good  excellent
---------- ---------- ---------- ----------
         1          3          0          2

--统计每年每个月的消费情况
select * from sale;
SUM_MONTH         SELL
--------- ------------
   200001      1000.00
   200002      1100.00
   200003      1200.00
   200004      1300.00
   200005      1400.00
   200006      1500.00
   200007      1600.00
   200101      1100.00
   200202      1200.00
   200301      1300.00

select substrb(sum_month, 1, 4) 年份,
         sum(decode(substrb(sum_month, 5, 2), '01', sell, 0)) 一月,
         sum(decode(substrb(sum_month, 5, 2), '02', sell, 0)) 二月,
         sum(decode(substrb(sum_month, 5, 2), '03', sell, 0)) 三月,
         sum(decode(substrb(sum_month, 5, 2), '04', sell, 0)) 四月,
         sum(decode(substrb(sum_month, 5, 2), '05', sell, 0)) 五月,
         sum(decode(substrb(sum_month, 5, 2), '06', sell, 0)) 六月,
         sum(decode(substrb(sum_month, 5, 2), '07', sell, 0)) 七月,
         sum(decode(substrb(sum_month, 5, 2), '08', sell, 0)) 八月,
         sum(decode(substrb(sum_month, 5, 2), '09', sell, 0)) 九月,
         sum(decode(substrb(sum_month, 5, 2), '10', sell, 0)) 十月,
         sum(decode(substrb(sum_month, 5, 2), '11', sell, 0)) 十一月,
         sum(decode(substrb(sum_month, 5, 2), '12', sell, 0)) 十二月
  from sale
 group by substrb(sum_month, 1, 4);
年份  一月   二月   三月   四月  五月   六月   七月   八月   九月  十月  十一月  十二月
---- ---- ------ ------ ------ ------ ------ ------ ------ ------ ----- ------ ------
2000  1000   1100  1200   1300   1400   1500  1600     0     0     0     0     0
2001  1100      0     0      0      0      0     0     0     0     0     0     0
2003  1300      0     0      0      0      0     0     0     0     0     0     0
2000     0   1200     0      0      0      0     0     0     0     0     0     0
 
Attention:统计中CASE的运用!!!
例子:
select * from hkb_case_test;
USERID EMPNO     SAL SEX
------ ----- ------- ---
     1 a         800   1
     1 a         800   1
     2 b         900   2
     3 a         400   1
     4 d        1400   2
     5 e        1200   1
     6 f         500   1
     7 a         300   2
     8 d        1000   1
     9 d        1230   2
    10 b        2000   2
    11 c        2000   1
    12 b        1200   1

select a.empno as 部门,
       count(a.userid) as 人数,
       sum(case a.sex
             when 1 then
              1
             else
              0
           end) as 男,
       sum(case a.sex
             when 2 then
              1
             else
              0
           end) as 女,
       sum(case sign(a.sal - 800)
             when -1 then
              1
             else
              0
           end) as 小于800元, --注意别名不能以数字开头
       sum((case sign(a.sal - 800) * sign(a.sal - 1000) --用*来实现<和>功能
             when -1 then
              1
             else
              0
           end) + (case a.sal
             when 800 then
              1
             else
              0
           end)) as 从800至999,
            sum((case sign(a.sal - 1000) * sign(a.sal - 1200)
         when -1 then
          1
         else
          0
       end) + (case a.sal
         when 1000 then
          1
         else
          0
       end)) as 从1000元至1199元,
       sum((case sign(a.sal - 1200)
             when 1 then
              1
             else
              0
           end) + (case a.sal
             when 1200 then
              1
             else
              0
           end)) as 大于1200元
  from hkb_case_test a
 group by a.empno;

部门  人数   男   女  小于800元 从800至999 从1000元至1199元 大于1200元
---- ------ ---- ---- --------- ---------- ---------------- ----------
a     4      3    1      2          2             0             0
b     3      1    2      0          1             0             2
c     1      1    0      0          0             0             1
e     1      1    0      0          0             0             1
d     3      1    2      0          0             1             2
f     1      1    0      1          0             0             0

分享到:
评论

相关推荐

    Oracle实现行列转换的方法分析

    本文将深入探讨Oracle中实现行列转换的几种方法。 首先,对于固定列数的行列转换,假设我们有一个学生成绩表,其中包含学生姓名、科目和分数。如果要将每个学生的各科成绩从多行展示转变为一行展示,可以使用Oracle...

    mysql 查询行列转换

    本篇文章将深入探讨“MySQL 查询行列转换”的概念及其实际应用,这在数据分析和报表展示时尤其重要。 行转列是数据处理中的常见需求,尤其是在数据透视或汇总分析时。在 MySQL 中,我们可以使用几种方法实现这一...

    通过SQL语句实现行列转换的几种方法

    2. **行转列**:与列转行相反,将行数据转换为列数据,适用于汇总统计等场景。 3. **多列转换成字符串**:将多列数据合并为一个字符串,便于存储或传输。 4. **多行转换成字符串**:将多行数据合并为一个字符串,是...

    SQL行列转换

    2. **PIVOT函数**:某些数据库系统(如Oracle,SQL Server)提供了`PIVOT`关键字,使得行列转换更为简洁。例如,在Oracle中,我们可以这样操作: ```sql WITH order_status AS ( SELECT product_id, status, COUNT...

    [数据库] SQL查询语句表行列转换及一行数据转换成两列1

    在SQL查询中,表的行列转换以及一行数据转换成两列是常见的操作,尤其是在数据分析和报表展示时。本文将详细讲解这些概念,并提供相应的SQL语句示例。 首先,我们从创建数据库表及插入数据开始。在例子中,创建了一...

    关于oracle decode函数的用法

    通过以上实例可以看出,DECODE函数在Oracle数据库中是一个非常灵活且强大的工具,能够帮助我们在查询中实现复杂的条件判断和数据处理,特别是在需要进行行列互换、数据聚合等场景下,DECODE函数的应用显得尤为关键。

    一个oracle客户端(oracle sql handler)

    可以直接对查询结果进行再操作,如 修改、插入行、删除行、提交(将表格中的数据改变写入相应的数据库表中)、多功能拷贝、导出为 INSERT 语句、单条记录操作、方便的查找及替换功能、数字统计、行列移动、列排序、...

    sql行列转换[借鉴].pdf

    在SQL中,行列转换是一种常见的数据操作,用于将表格数据从行格式转换为列格式,或者反之。在给定的PDF文件中,涉及到的具体知识点主要包括以下几个方面: 1. **CASE语句**:在SQL查询中,`CASE`语句常用于进行条件...

    oracle学习参考

    本篇将深入探讨Oracle中的字符串操作、行列转换以及批量处理等关键知识点。 1. **批量获取文件名** 在命令行环境下,可以通过批处理命令`DIR *.* /B &gt; LIST.TXT`来获取当前目录下的所有文件名,并将其保存到名为`...

    SQL语句实现对数据库查询结果的行列互换

    当我们要进行行列互换时,通常涉及到的是将某一列的值转换为行,或者将多行数据合并为一列。以下是一些常见的方法: 1. **使用UNION ALL操作符** 如果你希望将多行数据合并成一列,可以使用UNION ALL。假设我们有...

    sql行列互换

    其中,“行列互换”是一种常见的数据操作方式,尤其是在统计分析或数据报告中非常有用。接下来,我们将通过几个具体的例子来详细探讨如何在不同的数据库环境下实现“行列互换”。 #### 一、SQL Server 实现行列互换...

    震撼推出超方便实用的Oracle开发工具 - Oracle SQL Handler,双语界面,智能SQL编辑器,免装Oracle客户端,能运行于Windows, 双语界面

    交(将表格中的数据改变写入相应的数据库表中)、多功能拷贝、将选择的单元格数据导出为 XLS /CSV /INSERT SQL /HTML /XML 等格式、单条记录操作、能方便地查找\替换单元格中的数据、数值统计、行列移动、 ...

    oracle报表创建的学习

    - **矩阵式报表**(交叉表)显示数据的行列交叉,常用于统计分析,如按月份和销售人员分组的销售额。 - **邮件标签**则用于生成邮寄地址等特殊格式的输出。 3. **建立和修改Oracle报表** 创建报表时,应避免在一...

    Oracle单条SQL语句可以做什么.pdf

    综上所述,Oracle中的单条SQL语句可以通过各种高级功能实现复杂的查询逻辑,包括行列转换、处理重复值以及自定义合计函数等。这些技术的应用不仅能够提高查询效率,还能够简化数据处理流程,为企业提供更高效的数据...

    Oracle开发工具 - Oracle SQL Handler(功能强大,超方便好用, 免装客户端, Windows / Linux)

    便地查找\替换单元格中的数据、数值统计、行列移动、列排序、选择模式切换等;能方便 地查看/编辑大型的文本字段(如 CLOB、 LONG) 智能的SQL编辑器:自动弹出提示窗口,列出关键字、关键字组合、函数名、列名、...

    Oracle经典笔记

    "行转列.txt"涉及到数据透视或行列转换,这是数据分析时常见的需求,例如将一年的每个月销售额从行转化为列展示。 "SQL其它对象.txt"可能包含了对视图、索引、触发器等更高级概念的讨论,这些是优化查询性能和实现...

    我的新菜单

    5. "SQL竖表转换成横表统计":这可能涉及到SQL的聚合和透视操作,将垂直布局的数据转换为水平布局,便于统计分析。这种操作在报表生成和数据分析中非常常见。 6. "实现小数据量和海量数据的通用分页显示存储过程....

    SQL 通过行动态生成列

    在SQL查询中,将行数据转换为列,也称为行转列或行列互换,是数据分析和报表制作中常见的需求。这种操作对于呈现表格数据,尤其是处理统计汇总时非常有用。"SQL 通过行动态生成列"这个主题,就是探讨如何在SQL中实现...

    (c)模式存储数据库中数据字典的表和视图

    3. 分析函数(如`ANALYZE`)用于计算累计排名、移动平均数和报表聚合等复杂统计任务 4. 序列(Sequence)在Oracle中用于生成唯一的整数,`CURRVAL`返回序列当前值,`NEXTVAL`递增并返回新值 5. SQL别名(Alias)...

Global site tag (gtag.js) - Google Analytics