[英]sql grouping grades
我有一个科目表如下:
id Subject Grade Ext
100 Math 6 +
100 Science 4 -
100 Hist 3
100 Geo 2 +
100 CompSi 1
我期待一个班级(id = 100)中的每个学生 output 如下:
Grade Ext StudentGrade
6 + 1
6 0
6 - 0
5 + 0
5 0
5 - 0
4 + 0
4 0
4 - 1
3 + 0
3 1
3 - 0
2 + 1
2 0
2 - 0
1 + 0
1 1
1 - 0
我希望在 oracle/sql 而不是 UI 上完成此操作。 请输入任何内容。
你可以做这样的事情。 在 WITH 子句中,我为 1 到 6 年级以及 +、null 和 - 的“扩展”生成了两个小的“帮助”表(实际上是内联视图)。 在“扩展”视图中,我还创建了一个“排序”列,用于对最终的 output 进行排序(如果您想知道我为什么包含它)。
同样在 WITH 子句中,我包含了示例数据 - 您必须将其删除,而在主查询中使用您的实际表名。
这个想法是交叉连接“等级”和“扩展”,并将结果左外连接到您的输入数据。 从输入数据中计算成绩,按成绩和扩展名分组,并在过滤所需的 id 后。 连接条件中的decode
是必需的,因为对于扩展,我们希望将null
视为等于null
- decode
效果很好。
with
sample_inputs (id, subject, grade, ext) as (
select 100, 'Math' , 6, '+' from dual union all
select 100, 'Science', 4, '-' from dual union all
select 100, 'Hist' , 3, null from dual union all
select 100, 'Geo' , 2, '+' from dual union all
select 100, 'CompSi' , 1, null from dual
)
, g (grade) as (select level from dual connect by level <= 6)
, e (ord, ext) as (
select 1, '+' from dual union all
select 2, null from dual union all
select 3, '-' from dual
)
select g.grade, e.ext, count(t.grade) as studentgrade
from g cross join e left outer join sample_inputs t
on t.grade = g.grade and decode(t.ext, e.ext, 0) = 0
and t.id = 100 -- change this as needed!
group by g.grade, e.ext, e.ord
order by g.grade desc, e.ord
;
OUTPUT:
GRADE EXT STUDENTGRADE
----- --- ------------
6 + 1
6 0
6 - 0
5 + 0
5 0
5 - 0
4 + 0
4 0
4 - 1
3 + 0
3 1
3 - 0
2 + 1
2 0
2 - 0
1 + 0
1 1
1 - 0
您应该先生成行,然后再将它们与您的表连接起来,如下所示。 我在这里使用 with 子句在您的示例中生成 18 行。
with rws (grade, ext) as (
select ceil(level/3), decode(mod(level, 3), 0, '+', 1, '-', null)
from dual
connect by level <= 3 * 6
)
select r.grade, r.ext, nvl2(t.Ext, 1, 0) studentGrade
from rws r
left join your_table t
on t.Grade = r.Grade and decode(t.Ext, r.Ext, 1, 0) = 1
order by 1 desc, decode(r.ext, null, 2, '-', 3, '+', 1)
看起来您希望在加入学生和科目时填写稀疏数据。
从 Oracle 10g 开始,正确的方法是使用“分区外连接”。
该文档有示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.