【问题标题】:Group a query when teacher, subject are the same and there is no time interval between classes教师、科目相同且课间无时间间隔时分组查询
【发布时间】:2019-05-08 13:29:37
【问题描述】:

下面我将放置一些表的结构来说明我正在尝试做的事情。

考虑到每个学生的上课时间是30分钟,我想选择学生的课表,但是我需要将课表顺序(每个课表30分钟,没有间隔)和老师和主题相同

我使用的是 SQL Server 2017。

学生

id      name
1       Oliver
2       Jack
3       Harry

老师

id      name
1       Amelia
2       Olivia

主题

id       subject
1        Mathematics
2        Science

时间表

id  startdatetime            idstudent   idteacher    idsubject
1   2019-05-30 08:00         1            1           2
2   2019-05-30 08:40         1            1           2
3   2019-05-30 09:10         1            1           2
3   2019-05-30 09:40         1            2           2
4   2019-05-30 10:10         1            2           1

当按 idstudent 选择时,我想按如下分组显示结果:

Qty    startdatetime       teacher    subject
1      2019-05-30 08:00    Amelia     Science
2      2019-05-30 08:40    Amelia     Science   grouped in a single row(qty 2) because the class time has 30 minutes without interval, teacher and subject are the same.
1      2019-05-30 09:40    Olivia     Science
1      2019-05-30 10:10    Olivia     Mathematics

提前致谢!

【问题讨论】:

  • 您是否尝试过编写此查询?如果是这样,请将其添加到您的帖子中。
  • 时间戳[s 相隔 40 分钟,但您声称要在相隔 30 分钟时将它们分组。
  • @Gordon Linoff 分组的行是“2019-05-30 08:40”和“2019-05-30 09:10”
  • @Ryan Wilson 我的困难是我不知道如何比较课程之间是否有时间间隔。我从 SQL Server 开始。我什至认为我可以使用 CTE 或存储过程之类的东西,但由于我来自 Firebird,我遇到了很多麻烦
  • @Marcoscdoni 。 . .我更改了表格的格式,因此不需要滚动。当我查看数据时,它只在schedule 表中显示了四行,在所需结果中显示了四行——所以看起来没有任何东西被聚合。

标签: sql sql-server-2017


【解决方案1】:

这是一种群岛问题。我只关注schedule 表。您可以根据需要加入其他表格。

要确定组的开始位置,请使用lag()。然后累积和定义组和聚合得到你想要的:

select count(*) as qty,
       idstudent, idteacher, idsubject
from (select s.*,
             sum(case when prev_sdt > dateadd(minute, -30, startdatetime)
                      then 1 else 0
                 end) over (partition by s.idstudent, s.idteacher, s.idsubject order by s.startdatetime) as grp
      from (select s.*,
                   lag(s.startdatetime) over (partition by s.idstudent, s.idteacher, s.idsubject order by s.startdatetime) as prev_sdt
            from schedule s
           ) s
     ) s
group by by idstudent, idteacher, idsubject, grp
order by min(startdatetime);

【讨论】:

  • 谢谢@Gordon Linoff!我试试看
  • 用基本上只是代码转储的东西回答一个明显的家庭作业问题对未来的读者或 OP 没有帮助。真的可以像重复一样关闭,因为有很多其他问题有效地问同样的事情,例如。这个stackoverflow.com/questions/49931719/…得到了几乎完全相同的答案!
  • 你好@Gordon Linoff。你帮了我很多。还有一个问题:更改此查询以显示字段“startdatetime”和教师姓名的最佳方法是什么?
  • @Marcoscdoni 。 . .使用min() 作为开始日期时间。使用连接从引用表中引入名称。
  • @Gordon Linoff 经过一些测试后,我验证查询没有正确分组,所以我编辑了答案。如果您能检查一下,我将不胜感激。如果您可以再回答一个问题:在此查询中,我想逐行显示某个学生之前为当前行的该主题所做的总金额。我可以使用条件标准来做到这一点吗?示例:显示已为该主题完成的课程总数,但仅显示学生在场的课程?类似 count (*) where present = 1 再次感谢。
猜你喜欢
  • 1970-01-01
  • 2011-11-09
  • 2023-02-21
  • 1970-01-01
  • 2020-08-09
  • 2011-12-20
  • 2020-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多