繁体   English   中英

sql 分组等级

[英]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 开始,正确的方法是使用“分区外连接”。

该文档有示例。

https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/SELECT.html#GUID-CFA006CA-6FF1-4972-8211E-699614A

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM