sql 排序依据和分组汇总
sql order by with 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%
角色table
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. 依此类推。我试图在内部子句中使用 order by 但它没有帮助。它没有任何作用。添加外部 select 也不会改变任何东西。非常感谢任何帮助。谢谢。
在 comp
.
的表达式中目前有 sum(count(*))
的地方仅使用 count(*)
从您当前的查询开始,您可以只使用 avg()
:
SELECT
COALESCE(ROLE, 'Summary') ROLE,
COUNT(*) AS cases,
SUM(CASE WHEN PREPARED = 'Y' THEN 1 ELSE 0 END) AS prepped,
AVG(CASE WHEN PREPARED = 'Y' THEN 1 ELSE 0 END) AS ratio_completed
FROM ...
这个 returns 一个介于 0
和 1
之间的数字。如果您喜欢百分比(介于 0
和 100
之间),可以将 THEN 1
替换为 THEN 100
。
在 SQL 中将更复杂的逻辑拆分为多个子查询是一个很好的做法。
我建议使用一个子查询(基本上是您的查询)来计算计数,并另一个子查询来计算比率。
新的主要查询是
select ROLE, CASES, PREPPED,
(PREPPED/nullif(CASES,0))* 100 proc_completed
from (your query);
ROLE CASES PREPPED PROC_COMPLETED
--------------- ---------- ---------- --------------
State President 10 2 20
State Member 1 10 5 50
State Member 2 10 7 70
State Member 2 0 0
Summary 10 14 140
请注意,我在 count = 0 的边缘情况下添加了一个新行,并且我使用 nullif 函数来避免出现问题。
我的查询如下所示。输出
当前输出
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%
角色table
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. 依此类推。我试图在内部子句中使用 order by 但它没有帮助。它没有任何作用。添加外部 select 也不会改变任何东西。非常感谢任何帮助。谢谢。
在 comp
.
sum(count(*))
的地方仅使用 count(*)
从您当前的查询开始,您可以只使用 avg()
:
SELECT
COALESCE(ROLE, 'Summary') ROLE,
COUNT(*) AS cases,
SUM(CASE WHEN PREPARED = 'Y' THEN 1 ELSE 0 END) AS prepped,
AVG(CASE WHEN PREPARED = 'Y' THEN 1 ELSE 0 END) AS ratio_completed
FROM ...
这个 returns 一个介于 0
和 1
之间的数字。如果您喜欢百分比(介于 0
和 100
之间),可以将 THEN 1
替换为 THEN 100
。
在 SQL 中将更复杂的逻辑拆分为多个子查询是一个很好的做法。
我建议使用一个子查询(基本上是您的查询)来计算计数,并另一个子查询来计算比率。
新的主要查询是
select ROLE, CASES, PREPPED,
(PREPPED/nullif(CASES,0))* 100 proc_completed
from (your query);
ROLE CASES PREPPED PROC_COMPLETED
--------------- ---------- ---------- --------------
State President 10 2 20
State Member 1 10 5 50
State Member 2 10 7 70
State Member 2 0 0
Summary 10 14 140
请注意,我在 count = 0 的边缘情况下添加了一个新行,并且我使用 nullif 函数来避免出现问题。