zoukankan      html  css  js  c++  java
  • 笔记:Oracle SQL 高级查询简介 (1) case、层次化、扩展group by

    1. 集合操作

    union all 、 union、 intersect 、 minus

    注意:集合操作的所有查询返回的列数、列类型必须相同,但是列名可以不一样。


    2、translate 函数

    translate(x, str1, str2) . 在字段x 中查找str1中的字符,转化为str2中对应的字符。

    例子:

    select translate(x, 'abc', 'xyz') from table1 


    对字段x中字符进行替换:a->x, b->y, x->z


    3.DECODE() 函数

    就是case 语句。


    4、CASE 语句

    搜索case表达式 例子:

      select  e.employee_id, 
      case when e.salary>=10000 then 'good' 
           when e.salary>5000 and e.salary < 10000 then 'middle'
           else 'poor' 
           end as salary_type
       from hr.employees  e

    结果:

    EMPLOYEE_ID SALARY_TYPE
    ----------- -----------
            100 good
            101 good
            102 good
            103 middle
            104 middle
            105 poor
            106 poor
            107 poor
            108 good


    简单case表达式 例子:

      select e.employee_id , 
      case e.department_id 
      when 90 then 'research'
      when 60 then 'sales'
      else 'unkown'
      end as department
      from hr.employees e


    结果:

    EMPLOYEE_ID DEPARTMENT
    ----------- ----------
            100 research
            101 research
            102 research
            103 sales
            104 sales
            105 sales
            106 sales
            107 sales
            108 unkown

     
    5、层次化查询


    使用 start with 和 connect to privor

    select level , e.employee_id , e.manager_id,  e.first_name||' '|| e.last_name as full_name
      from hr.employees e 
      start with e.employee_id = 100
      connect by prior e.employee_id = e.manager_id
      order by level


    结果:

         LEVEL EMPLOYEE_ID MANAGER_ID FULL_NAME
    ---------- ----------- ---------- ----------------------------------------------
             1         100            Steven King
             2         102        100 Lex De Haan
             2         114        100 Den Raphaely
             2         120        100 Matthew Weiss
             2         121        100 Adam Fripp
             2         122        100 Payam Kaufling
             2         123        100 Shanta Vollman
             2         124        100 Kevin Mourgos
             2         145        100 John Russell
             2         146        100 Karen Partners
             2         147        100 Alberto Errazuriz
             2         148        100 Gerald Cambrault
             2         149        100 Eleni Zlotkey
             2         201        100 Michael Hartstein
             2         101        100 Neena Kochhar
             3         108        101 Nancy Greenberg
             3         200        101 Jennifer Whalen
             3         203        101 Susan Mavris
             3         204        101 Hermann Baer
             3         205        101 Shelley Higgins


    添加过滤条件:

    select level , e.employee_id , e.manager_id,  e.first_name||' '|| e.last_name as full_name
      from hr.employees e 
      where e.last_name != 'Kochhar'
      start with e.employee_id = 100
      connect by prior e.employee_id = e.manager_id
      order by level


    以上语句滤除了Kochhar这个人(id=101),但是Kochhar的下属还会出现在结果中:

         LEVEL EMPLOYEE_ID MANAGER_ID FULL_NAME
    ---------- ----------- ---------- ----------------------------------------------
             1         100            Steven King
             2         114        100 Den Raphaely
             2         120        100 Matthew Weiss
             2         121        100 Adam Fripp
             2         122        100 Payam Kaufling
             2         201        100 Michael Hartstein
             2         124        100 Kevin Mourgos
             2         145        100 John Russell
             2         146        100 Karen Partners
             2         147        100 Alberto Errazuriz
             2         148        100 Gerald Cambrault
             2         149        100 Eleni Zlotkey
             2         102        100 Lex De Haan
             2         123        100 Shanta Vollman
             3         108        101 Nancy Greenberg
             3         200        101 Jennifer Whalen
             3         203        101 Susan Mavris
             3         204        101 Hermann Baer
             3         205        101 Shelley Higgins
             3         103        102 Alexander Hunold


    要一起滤除John 的下属,必须这样写

    select level , e.employee_id , e.manager_id,  e.first_name||' '|| e.last_name as full_name
      from hr.employees e  
      start with e.employee_id = 100
      connect by prior e.employee_id = e.manager_id and e.last_name != 'Kochhar'
      order by level

    这样结果为:

         LEVEL EMPLOYEE_ID MANAGER_ID FULL_NAME
    ---------- ----------- ---------- ----------------------------------------------
             1         100            Steven King
             2         114        100 Den Raphaely
             2         120        100 Matthew Weiss
             2         121        100 Adam Fripp
             2         122        100 Payam Kaufling
             2         201        100 Michael Hartstein
             2         124        100 Kevin Mourgos
             2         145        100 John Russell
             2         146        100 Karen Partners
             2         147        100 Alberto Errazuriz
             2         148        100 Gerald Cambrault
             2         149        100 Eleni Zlotkey
             2         102        100 Lex De Haan
             2         123        100 Shanta Vollman
             3         103        102 Alexander Hunold
             3         115        114 Alexander Khoo
             3         116        114 Shelli Baida
             3         117        114 Sigal Tobias
             3         118        114 Guy Himuro
             3         119        114 Karen Colmenares


    6. 扩展的Group By子句

    (1). ROLLUP子句

    为每一个分组返回一条记录,并为全部分组返回总计。

    select e.department_id , avg(e.salary)  from hr.employees e 
    where e.department_id is not null group by rollup(e.department_id) ;

    结果:

    DEPARTMENT_ID AVG(E.SALARY)
    ------------- -------------
               10          4400
               20          9500
               30          4150
               40          6500
               50          3475.55555555
               60          5760
               70         10000
               80          8955.88235294
               90          19333.3333333
              100           8601.33333333
              110          10154
                            6456.75471698
    12 rows selected

    可以在多列上统计

    select e.department_id , e.job_id, avg(e.salary)  from hr.employees e 
    where e.department_id is not null and e.job_id is  not null
    group by rollup(e.department_id, e.job_id) ;


    结果:

    DEPARTMENT_ID JOB_ID     AVG(E.SALARY)
    ------------- ---------- -------------
               10 AD_ASST             4400
               10                     4400
               20 MK_MAN             13000
               20 MK_REP              6000
               20                     9500
               30 PU_MAN             11000
               30 PU_CLERK            2780
               30                     4150
               40 HR_REP              6500
               40                     6500
               50 ST_MAN              7280
               50 SH_CLERK            3215
               50 ST_CLERK            2785
               50                      3475.55555555
               60 IT_PROG             5760
               60                     5760
               70 PR_REP             10000
               70                    10000
               80 SA_MAN             12200
               80 SA_REP              8396.55172413 
               80                     8955.88235294
               90 AD_VP              17000
               90 AD_PRES            24000
               90                    19333.3333333
              100 FI_MGR             12008
              100 FI_ACCOUNT          7920
              100                      8601.33333333
              110 AC_MGR             12008
              110 AC_ACCOUNT          8300
              110                    10154
                                      6456.75471698
    31 rows selected

    (2).CUBE

    为每一个分组返回一条记录,并为全部小组组合返回总计,并给出统计。

    select e.department_id , e.job_id, avg(e.salary)  from hr.employees e 
    where e.department_id is not null and e.job_id is  not null
    group by cube(e.department_id, e.job_id) 
    order by e.department_id, e.job_id;

    结果:

    DEPARTMENT_ID JOB_ID     AVG(E.SALARY)
    ------------- ---------- -------------
               10 AD_ASST             4400
               10                     4400
               20 MK_MAN             13000
               20 MK_REP              6000
               20                     9500
               30 PU_CLERK            2780
               30 PU_MAN             11000
               30                     4150
               40 HR_REP              6500
               40                     6500
               50 SH_CLERK            3215
               50 ST_CLERK            2785
               50 ST_MAN              7280
               50                     3475.55555555
               60 IT_PROG             5760
               60                     5760
               70 PR_REP             10000
               70                    10000
               80 SA_MAN             12200
               80 SA_REP              8396.55172413 
               80                     8955.88235294
               90 AD_PRES            24000
               90 AD_VP              17000
               90                    19333.3333333
              100 FI_ACCOUNT          7920
              100 FI_MGR             12008
              100                     8601.33333333
              110 AC_ACCOUNT          8300
              110 AC_MGR             12008
              110                    10154
                  AC_ACCOUNT          8300
                  AC_MGR             12008
                  AD_ASST             4400
                  AD_PRES            24000
                  AD_VP              17000
                  FI_ACCOUNT          7920
                  FI_MGR             12008
                  HR_REP              6500
                  IT_PROG             5760
                  MK_MAN             13000
                  MK_REP              6000 
                  PR_REP             10000
                  PU_CLERK            2780
                  PU_MAN             11000
                  SA_MAN             12200
                  SA_REP              8396.55172413
                  SH_CLERK            3215
                  ST_CLERK            2785
                  ST_MAN              7280
                                      6456.75471698
    50 rows selected

    (3). GROUPING 函数

    接收一列,列为空则返回1,非空则返回0.

    select grouping(e.department_id), e.department_id , avg(e.salary)  from hr.employees e 
    where e.department_id is not null group by rollup(e.department_id)

    结果:

    GROUPING(E.DEPARTMENT_ID) DEPARTMENT_ID AVG(E.SALARY)
    ------------------------- ------------- -------------
                            0            10          4400
                            0            20          9500
                            0            30          4150
                            0            40          6500
                            0            50           3475.55555555
                            0            60          5760
                            0            70         10000
                            0            80          8955.88235294
                            0            90         19333.3333333
                            0           100          8601.33333333
                            0           110         10154
                            1               6456.75471698
    12 rows selected


    与case when 配合:

    select case when grouping(e.department_id)=0 then ''||e.department_id else 'All Departments' end as department_id  ,
    case when grouping(e.job_id)=0 then e.job_id else 'All Jobs' end as job_id, avg(e.salary) 
    from hr.employees e 
    where e.department_id is not null and e.job_id is  not null
    group by cube(e.department_id, e.job_id) 
    order by e.department_id, e.job_id;

    结果:

    DEPARTMENT_ID                            JOB_ID     AVG(E.SALARY)
    ---------------------------------------- ---------- -------------
    10                                       AD_ASST             4400
    10                                       All Jobs            4400
    20                                       MK_MAN             13000
    20                                       MK_REP              6000
    20                                       All Jobs            9500
    30                                       PU_CLERK            2780
    30                                       PU_MAN             11000
    30                                       All Jobs            4150
    40                                       HR_REP              6500
    40                                       All Jobs            6500
    50                                       SH_CLERK            3215
    50                                       ST_CLERK            2785
    50                                       ST_MAN              7280
    50                                       All Jobs   3475.55555555
    60                                       IT_PROG             5760
    60                                       All Jobs            5760
    70                                       PR_REP             10000
    70                                       All Jobs           10000
    80                                       SA_MAN             12200
    80                                       SA_REP     8396.55172413 
    80                                       All Jobs   8955.88235294
    90                                       AD_PRES            24000
    90                                       AD_VP              17000
    90                                       All Jobs   19333.3333333
    100                                      FI_ACCOUNT          7920
    100                                      FI_MGR             12008
    100                                      All Jobs   8601.33333333
    110                                      AC_ACCOUNT          8300
    110                                      AC_MGR             12008
    110                                      All Jobs           10154
    All Departments                          AC_ACCOUNT          8300
    All Departments                          AC_MGR             12008
    All Departments                          AD_ASST             4400
    All Departments                          AD_PRES            24000
    All Departments                          AD_VP              17000
    All Departments                          FI_ACCOUNT          7920
    All Departments                          FI_MGR             12008
    All Departments                          HR_REP              6500
    All Departments                          IT_PROG             5760
    All Departments                          MK_MAN             13000
    All Departments                          MK_REP              6000 
    All Departments                          PR_REP             10000
    All Departments                          PU_CLERK            2780
    All Departments                          PU_MAN             11000
    All Departments                          SA_MAN             12200
    All Departments                          SA_REP     8396.55172413
    All Departments                          SH_CLERK            3215
    All Departments                          ST_CLERK            2785
    All Departments                          ST_MAN              7280
    All Departments                          All Jobs   6456.75471698
    50 rows selected

    (4). GROUPING SETS

    grouping sets 只返回小计信息。

    select e.department_id , e.job_id, avg(e.salary)  from hr.employees e 
    where e.department_id is not null and e.job_id is  not null
    group by grouping sets(e.department_id, e.job_id) 
    order by e.department_id, e.job_id;


    结果:

    DEPARTMENT_ID JOB_ID     AVG(E.SALARY)
    ------------- ---------- -------------
               10                     4400
               20                     9500
               30                     4150
               40                     6500
               50                     3475.55555555
               60                     5760
               70                    10000
               80                     8955.88235294
               90                    19333.3333333
              100                     8601.33333333
              110                    10154
                  AC_ACCOUNT          8300
                  AC_MGR             12008
                  AD_ASST             4400
                  AD_PRES            24000
                  AD_VP              17000
                  FI_ACCOUNT          7920
                  FI_MGR             12008
                  HR_REP              6500
                  IT_PROG             5760 
                  MK_MAN             13000
                  MK_REP              6000
                  PR_REP             10000
                  PU_CLERK            2780
                  PU_MAN             11000
                  SA_MAN             12200
                  SA_REP              8396.55172413
                  SH_CLERK            3215
                  ST_CLERK            2785
                  ST_MAN              7280
    30 rows selected


    (5).GROUPING_ID 函数

    相当于钱几个列的GROUPING值的组合。以下SQL

    select grouping(e.department_id),  grouping(e.job_id), grouping_id(e.department_id, e.job_id) as my_grouping_id,
    e.department_id , e.job_id, avg(e.salary)  from hr.employees e 
    where e.department_id is not null and e.job_id is  not null
    group by cube(e.department_id, e.job_id) 
    order by e.department_id, e.job_id;

    返回:

    GROUPING(E.DEPARTMENT_ID) GROUPING(E.JOB_ID) MY_GROUPING_ID DEPARTMENT_ID JOB_ID     AVG(E.SALARY)
    ------------------------- ------------------ -------------- ------------- ---------- -------------
                            0                  0              0            10 AD_ASST             4400
                            0                  1              1            10                     4400
                            0                  0              0            20 MK_MAN             13000
                            0                  0              0            20 MK_REP              6000
                            0                  1              1            20                     9500
                            0                  0              0            30 PU_CLERK            2780
                            0                  0              0            30 PU_MAN             11000
                            0                  1              1            30                     4150
                            0                  0              0            40 HR_REP              6500
                            0                  1              1            40                     6500
                            0                  0              0            50 SH_CLERK            3215
                            0                  0              0            50 ST_CLERK            2785
                            0                  0              0            50 ST_MAN              7280
                            0                  1              1            50            3475.55555555
                            0                  0              0            60 IT_PROG             5760
                            0                  1              1            60                     5760
                            0                  0              0            70 PR_REP             10000
                            0                  1              1            70                    10000
                            0                  0              0            80 SA_MAN             12200
                            0                  0              0            80 SA_REP     8396.55172413 
                            0                  1              1            80            8955.88235294
                            0                  0              0            90 AD_PRES            24000
                            0                  0              0            90 AD_VP              17000
                            0                  1              1            90            19333.3333333
                            0                  0              0           100 FI_ACCOUNT          7920
                            0                  0              0           100 FI_MGR             12008
                            0                  1              1           100            8601.33333333
                            0                  0              0           110 AC_ACCOUNT          8300
                            0                  0              0           110 AC_MGR             12008
                            0                  1              1           110                    10154
                            1                  0              2               AC_ACCOUNT          8300
                            1                  0              2               AC_MGR             12008
                            1                  0              2               AD_ASST             4400
                            1                  0              2               AD_PRES            24000
                            1                  0              2               AD_VP              17000
                            1                  0              2               FI_ACCOUNT          7920
                            1                  0              2               FI_MGR             12008
                            1                  0              2               HR_REP              6500
                            1                  0              2               IT_PROG             5760
                            1                  0              2               MK_MAN             13000
                            1                  0              2               MK_REP              6000 
                            1                  0              2               PR_REP             10000
                            1                  0              2               PU_CLERK            2780
                            1                  0              2               PU_MAN             11000
                            1                  0              2               SA_MAN             12200
                            1                  0              2               SA_REP     8396.55172413
                            1                  0              2               SH_CLERK            3215
                            1                  0              2               ST_CLERK            2785
                            1                  0              2               ST_MAN              7280
                            1                  1              3                          6456.75471698
    50 rows selected


    GROUPING_ID 与having 联合使用,可以过滤出想需要的统计值。

    (6). GROUP_ID

    在group by 中可以多次使用同一列,这样可以实现对数据的重新组织,或者按照不同的数据分组进行统计。

    select e.department_id , e.job_id, avg(e.salary)  from hr.employees e 
    where e.department_id is not null and e.job_id is  not null
    group by e.department_id, rollup(e.department_id, e.job_id)  

    结果:

    DEPARTMENT_ID JOB_ID     AVG(E.SALARY)
    ------------- ---------- -------------
               10 AD_ASST             4400
               20 MK_MAN             13000
               20 MK_REP              6000
               30 PU_MAN             11000
               30 PU_CLERK            2780
               40 HR_REP              6500
               50 ST_MAN              7280
               50 SH_CLERK            3215
               50 ST_CLERK            2785
               60 IT_PROG             5760
               70 PR_REP             10000
               80 SA_MAN             12200
               80 SA_REP              8396.55172413
               90 AD_VP              17000
               90 AD_PRES            24000
              100 FI_MGR             12008
              100 FI_ACCOUNT          7920
              110 AC_MGR             12008
              110 AC_ACCOUNT          8300
               10                     4400 
               20                     9500
               30                     4150
               40                     6500
               50                     3475.55555555
               60                     5760
               70                    10000
               80                     8955.88235294
               90                    19333.3333333
              100                      8601.33333333
              110                    10154
               10                     4400
               20                     9500
               30                     4150
               40                     6500
               50                     3475.55555555
               60                     5760
               70                    10000
               80                     8955.88235294
               90                    19333.3333333
              100                     8601.33333333
              110                    10154


    结果中有重复的分组,可以使用GROUP_ID消除。

    group_id 不接受任何参数,如果某个特定的分组出现n次,那么grouo_id返回从0到n-1之间的整数。

    如改写以上SQL为:

    select e.department_id , e.job_id, group_id(), avg(e.salary)  from hr.employees e 
    where e.department_id is not null and e.job_id is  not null
    group by e.department_id, rollup(e.department_id, e.job_id)  


    结果为:

    DEPARTMENT_ID JOB_ID     GROUP_ID() AVG(E.SALARY)
    ------------- ---------- ---------- -------------
               10 AD_ASST             0          4400
               20 MK_MAN              0         13000
               20 MK_REP              0          6000
               30 PU_MAN              0         11000
               30 PU_CLERK            0          2780
               40 HR_REP              0          6500
               50 ST_MAN              0          7280
               50 SH_CLERK            0          3215
               50 ST_CLERK            0          2785
               60 IT_PROG             0          5760
               70 PR_REP              0         10000
               80 SA_MAN              0         12200
               80 SA_REP              0          8396.55172413
               90 AD_VP               0         17000
               90 AD_PRES             0         24000
              100 FI_MGR              0         12008
              100 FI_ACCOUNT          0          7920
              110 AC_MGR              0         12008
              110 AC_ACCOUNT          0          8300
               10                     0          4400 
               20                     0          9500
               30                     0          4150
               40                     0          6500
               50                     0          3475.55555555
               60                     0          5760
               70                     0         10000
               80                     0          8955.88235294
               90                     0         19333.3333333
              100                     0          8601.33333333
              110                     0         10154
               10                     1          4400
               20                     1          9500
               30                     1          4150
               40                     1          6500
               50                     1          3475.55555555
               60                     1          5760
               70                     1         10000
               80                     1          8955.88235294
               90                     1         19333.3333333 
              100                     1          8601.33333333
              110                     1         10154  


    与HAVING 子句联合使用,则可以消除重复的列。 


  • 相关阅读:
    云端开发,云端部署
    Chrome下的Page Speed使用
    Linux的到来
    NoSQL 之 Morphia 操作 MongoDB
    qTip2
    在.NET下使用Task Parallel Library提高程序性能
    WCF REST系列文章汇总
    Google工具pagespeed使用教程
    从零开始系统深入学习android
    如何优化一个网站使之提高访问速度
  • 原文地址:https://www.cnblogs.com/leeeee/p/7276072.html
Copyright © 2011-2022 走看看