在Oracle11g中使用Level进行排序

问题描述 投票:3回答:1

我正在尝试使用Oracle11g中的LEVEL功能创建组织结构。

我有以下查询:

SELECT
  level,
  lpad(' ', 3 * (level - 1)) || em.empno || ' : ' || em.fname || ' ' || em.lname "Employee",
  em.position                                                                    "Position",
  outno || ': ' || ou.street || ' ' || ou.city || ' ' || ou.zipcode              "Outlet",
  count(DISTINCT fa.reportnum)                                                   "# of Fault Reports"
FROM employee em
  INNER JOIN outlet ou USING (outno)
  LEFT JOIN faultreport fa ON fa.empno = em.empno AND fa.datechecked > (SYSDATE - 91)
START WITH em.empno = 30012
CONNECT BY PRIOR em.empno = em.supervisorno
GROUP BY level,
  em.empno, em.fname, em.lname, em.position,
  outno, ou.street, ou.city, ou.zipcode;

这给了我以下输出:

LEVEL Employee                          Position             Outlet                         # of Fault Reports
----- --------------------------------- -------------------- ------------------------------ ------------------
    1 30012 : Moreno Bale               Owner                119: Forrest Adelaide 5005                      0
    2    45611 : Annah Marlek           Area_Manager         112: Beauford Port Cambia 5001                  0
    2    48900 : Geoff Hanna            Area_Manager         118: Icecream Iyanee 5008                       0
    3       23490 : Abel Cole           Admin_Assistant      116: Huntington Banshee 5007                    0
    3       31459 : Chris Boss          Admin_Assistant      119: Forrest Adelaide 5005                      0
    3       60021 : Beau Rueford        Admin_Assistant      111: Junlee Caprice 5009                        0
    3       67823 : Jess Fred           Head_Mechanic        114: Elephant Ocupus 5004                       0
    4          55601 : Kabil Malla      Mechanic             115: Dundee Eeyrie 5003                         1
    4          55602 : Harry Potter     Mechanic             111: Junlee Caprice 5009                        5
    4          60020 : Maria Marbosa    Sales_Rep            113: Cathany Zeus 5002                          0
    4          77689 : Javier Martin    Sales_Rep            112: Beauford Port Cambia 5001                  0

11 rows selected.

但是,当我看到表格时,这是确切的关系:

Employee    Manager
    30012   -
    48900   30012
    45611   30012
    23490   45611
    31459   48900
    67823   48900
    55602   67823
    55601   67823
    60021   48900
    77689   60021
    60020   60021

我如何在Oracle中实现它,以便我有以下输出:

LEVEL Employee                          Position             Outlet                         # of Fault Reports
----- --------------------------------- -------------------- ------------------------------ ------------------
    1 30012 : Moreno Bale               Owner                119: Forrest Adelaide 5005                      0
    2    45611 : Annah Marlek           Area_Manager         112: Beauford Port Cambia 5001                  0
    3       23490 : Abel Cole           Admin_Assistant      116: Huntington Banshee 5007                    0
    2    48900 : Geoff Hanna            Area_Manager         118: Icecream Iyanee 5008                       0
    3       31459 : Chris Boss          Admin_Assistant      119: Forrest Adelaide 5005                      0
    3       60021 : Beau Rueford        Admin_Assistant      111: Junlee Caprice 5009                        0
    4          60020 : Maria Marbosa    Sales_Rep            113: Cathany Zeus 5002                          0
    4          77689 : Javier Martin    Sales_Rep            112: Beauford Port Cambia 5001                  0
    3       67823 : Jess Fred           Head_Mechanic        114: Elephant Ocupus 5004                       0
    4          55601 : Kabil Malla      Mechanic             115: Dundee Eeyrie 5003                         1
    4          55602 : Harry Potter     Mechanic             111: Junlee Caprice 5009                        5

11 rows selected.

请注意,如果经理管理的员工人数超过1人,则根据员工编号扩展树。

谢谢!

sql oracle sorting oracle11g hierarchical-data
1个回答
3
投票

您的数据的解释缺乏许多细节。无论如何,你试图执行的查询和你的例外输出,我想错误是你试图同时做很多事情:聚合和分层查询在一起。

为了获得所需的输出,connect by应该是查询评估的最后一步,但是在查询之前无法对聚合进行评估。

通过评估连接按预期顺序返回行,但是分组子句在其评估中定义了一个隐式排序,它会覆盖它,给出由分组键排序的行。

通常,SQL语句处理按以下顺序评估查询子句:

  1. FROM + WHERE + CONNECT BY
  2. 通过...分组
  3. HAVING
  4. 选择
  5. 订购

因此,您应该通过子查询来分离这两个事物,该子查询在执行分层查询阶段之前评估计数聚合,而不对输出进行排序。

您可以尝试此查询:

SELECT LEVEL, LPAD(' ', 3*(LEVEL - 1)) || empno || ' : ' || EM.fname || ' ' || EM.lname "Employee", 
    EM.position "Position", outno || ': ' || OU.street || ' ' || OU.city || ' ' || OU.zipcode "Outlet", 
    dist_reportnums "# of Fault Reports" 
FROM employee EM
    JOIN outlet OU using (outno) 
    LEFT JOIN (
            selec empno, COUNT(DISTINCT FA.reportnum) as dist_reportnums
            from faultreport FA
            where FA.datechecked > (SYSDATE - 91)
            GROUP BY empno
        ) using (empno)
START WITH empno = 30012
CONNECT BY PRIOR empno = EM.supervisorno
© www.soinside.com 2019 - 2024. All rights reserved.