如何编号行,总计结尾?

时间:2013-12-02 23:09:58

标签: sql oracle group-by running-total rollup

我当前的sql:

select s.dcid, substr(s.lastfirst,0,3),  to_char(a.att_date, 'mm/dd/yyyy'), a.periodid, p.name,     a.attendance_codeid, ac.att_code, count(*)

from students s
join attendance a on s.id = a.studentid
join period p on a.periodid = p.id
join attendance_code ac on a.attendance_codeid = ac.id

WHERE ac.att_code IS NOT NULL 
AND s.schoolid = 109
AND s.enroll_status = 0
AND s.student_number = 100887
AND a.att_date >= to_date('08/15/2013', 'mm/dd/yyyy')


group by s.dcid, s.lastfirst,  to_char(a.att_date, 'mm/dd/yyyy'), a.periodid, p.name, a.attendance_codeid, ac.att_code

输出: sql ouput

我想让输出顺序编号count(*)列所在的每个记录,在每个新组中以1开头,并将总数放在组的底部,但我不知道如何要做到这一点。我已经尝试通过表达式在组的各个部分进行汇总,但最终会给出日期,句号等的小计...我只需要为学生提供总数(s.dcid或s.lastfirst)

[每个请求的附加信息......]

我希望能够获得一份报告,我的最终用户可以搜索在日期范围内拥有一定数量的出勤记录的学生。例如,如果最终用户想要找到在10/1/2013和10/31/2013之间缺席20次的学生,其中att_code是A,C,E,G ...等之一。一旦报告运行,我想向他们展示缺席发生的日期,以及用作视觉验证的代码,记录确实与他们的搜索条件相符。

输出应该看起来像当前输出,但COUNT(*)列除外,这是我现在挂断的地方。我喜欢row_number如何按顺序为每条记录编号,但我仍在寻找的是当小组(学生)改变时如何重置顺序编号。

例如......

DCID  S.LASTFIRST  A.ATT_DATE  PERIODID  NAME  ATT_CODE  COUNT(or # or Num...)
1006  Aco          08/29/2013      1704  4     W             1
1006  Aco          09/03/2013      1701  1     6             2
1006  Aco          09/05/2013      1706  6     G             3
...
1006  Aco          10/04/2013      1706  6     z            20
2543  Bro          08/29/2013      1704  4     W             1
2543  Bro          09/03/2013      1701  1     6             2
2543  Bro          09/05/2013      1706  6     G             3
...
2543  Bro          10/04/2013      1706  6     z            20
3121  Com          08/29/2013      1704  4     W             1
3121  Com          09/03/2013      1701  1     6             2
3121  Com          09/05/2013      1706  6     G             3
...
3121  Com          10/04/2013      1706  6     z            20

当然,在这个例子中,我通过用'...'替换三组中每一组中的行号4 - 19来缩写输出。我不想直接输出它。

2 个答案:

答案 0 :(得分:0)

ROW_NUMBER()分析函数将毫不奇怪地使用分区按顺序对行进行编号并按顺序排序。

select s.dcid,
       substr(s.lastfirst,0,3),
       to_char(a.att_date, 'mm/dd/yyyy'),
       a.periodid,
       p.name,
       a.attendance_codeid,
       ac.att_code,
       ROW_NUMBER() OVER ( ORDER BY s.dcid )
from students s
join attendance a on s.id = a.studentid
join period p on a.periodid = p.id
join attendance_code ac on a.attendance_codeid = ac.id

WHERE ac.att_code IS NOT NULL 
AND s.schoolid = 109
AND s.enroll_status = 0
AND s.student_number = 100887
AND a.att_date >= to_date('08/15/2013', 'mm/dd/yyyy')
GROUP BY s.dcid,
         s.lastfirst,
         to_char(a.att_date, 'mm/dd/yyyy'),
         a.periodid,
         p.name,
         a.attendance_codeid,
         ac.att_code;

在屏幕截图中,COUNT()列始终为1,因此ROW_NUMBER()也将始终为1(因为它似乎是每个组的最大尺寸)。

如果情况并非如此,那么您需要在GROUP BY条款中限制较少 - 但是您没有提供足够的信息来确定您希望查询对我做什么进行任何更改

答案 1 :(得分:0)

使用ROW_NUMBER功能如下:

SELECT s.dcid,
       SUBSTR (s.lastfirst, 0, 3),
       TO_CHAR (a.att_date, 'mm/dd/yyyy'),
       a.periodid,
       p.name,
       a.attendance_codeid,
       ac.att_code,
       ROW_NUMBER() OVER (ORDER BY s.dcid) AS rownumber
       -- I have ordered by s.dcid. You can order by whichever column you want.
  FROM students s
       JOIN attendance a ON s.id = a.studentid
       JOIN period p ON a.periodid = p.id
       JOIN attendance_code ac ON a.attendance_codeid = ac.id
 WHERE     ac.att_code IS NOT NULL
       AND s.schoolid = 109
       AND s.enroll_status = 0
       AND s.student_number = 100887
       AND a.att_date >= TO_DATE ('08/15/2013', 'mm/dd/yyyy');