簡體   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