首页 > 解决方案 > 带有内部选择子句的sql order by和group by rollup

问题描述

我的查询如下所示。输出

电流输出

Role            Cases prepped % Completed    
State Member 1  10    5       50%
State Member 2  10    7       70%
State President 10    2       20%
Summary         30    14      46.6%

预期产出

Role            Cases prepped % Completed
State President 10    2       20%
State Member 1  10    5       50%
State Member 2  10    7       70%
Summary         30    14      46%

角色表

id name
30 State President
40 State Member

这是我的查询,

SELECT COALESCE(ROLE, 'Summary') ROLE,   
       count(*) AS cases, 
       SUM(CASE WHEN PREPARED = 'Y' THEN 1
                ELSE 0
           END) AS prepped, 
 round(avg(case when prepared = 'Y' then 100 else 0 end),2)||'%' as % Completed
FROM
  (SELECT CASE
              WHEN r.id = 30 THEN r.name
              ELSE r.name || ' ' || u.case_member_id
          END AS ROLE,
          bi.prepared
   FROM cases c
   LEFT JOIN case_inventory ci ON ci.case_id = c.id
   AND c.id = ci.case_id
   AND c.delete_date IS NULL
   AND ci.case_id =40
  Left JOIN users u ON ci.assigned_to = u.id
   Left JOIN ROLES r ON u.role_id = r.id
   Left JOIN user_cases_map uc ON c.id = uc.case_id
   AND uc.id = 1572919346)
GROUP BY ROLLUP (ROLE);

我现在想根据角色对行进行排序。第一个记录应该是国家总统,然后是国家成员 1。国家成员 2。依此类推。我试图在内部子句中排序,但没有帮助。它没有任何作用。添加外部选择也不会改变任何东西。任何帮助高度赞赏。谢谢你。

标签: sqloracle

解决方案


你可以做这样的事情。我没有你的输入数据,所以我用SCOTT.EMP了。

注意几件事。我按 分组JOB,我同时使用GROUPING(JOB)了 in (为摘要行SELECT添加标签)和 in 。由于我在(用于输出列)中重用列名,因此我必须小心限定列名(为了清楚起见,我指的是输入表列,而不是列在- 如果中的列名不合格)。因此,需要在 中限定列名,这迫使我在子句中为表起别名(否则我将不得不在任何地方都携带完整的表名)。TOTALORDER BYJOBSELECTORDER BYJOBSELECTORDER BYORDER BYFROM

如果可以,使用GROUPINGin SELECT(而不是NVL) 中的函数特别重要。您不希望标记作业组- 您只希望为汇总行标记。这一点甚至让很多非常高级的程序员都感到困惑。JOBnullnullTOTAL

我将展示如何“手动”决定顺序:PRESIDENT首先,然后MANAGER是 ,然后是所有其他作业(按字母顺序排列)。如果您将优先级顺序保存在某处,例如在表中,您可以加入该表并CASE在我的查询中使用排序列而不是“手动”表达式。

select case grouping(job) when 0 then job else 'TOTAL' end as job
     , sum(sal) as total_salary
from   scott.emp e
group  by rollup(job)
order  by grouping(e.job)       -- to get the total in the last row
        , case e.job when 'PRESIDENT' then 1 when 'MANAGER' then 2 end
        , e.job
;

JOB       TOTAL_SALARY
--------- ------------
PRESIDENT         5000
MANAGER           8275
ANALYST           6000
CLERK             4150
SALESMAN          5600
TOTAL            29025

推荐阅读