麻烦概念化查询

时间:2013-12-10 18:35:54

标签: mysql sql

我有一个'Course'表和一个'Event'表。 我想拥有实际发生的所有课程,即它们不会被活动取消。

我通过对所有课程和脚本分析(基本上是一些循环)的简单请求完成了这个,但是这个请求需要一段时间,我相信太久了。我认为我想要的是一个查询,没有循环来优化这个请求。

以下是详细信息:

  • 'Course' c包含字段'date''duration'以及与'Grade'表格的多对多关系
  • 'Event' e包含字段'begin''end''break'以及与'Grade'表格的多对多关系
  • 如果某个课程同时发生并且该活动是休息时间(e.break = 1
  • ,则会取消该课程
  • 如果课程的所有等级都在同一时间发生的事件中,那么课程将被事件取消(可能会发生许多事件,我必须总结这些事件的等级并将它们与等级进行比较课程)。这是我在循环中所做的部分,我在构思这一点时遇到了一些麻烦。

欢迎任何帮助,

提前致谢,

PS:我正在使用mysql

编辑:表格详情

道菜的

+-----------+-------------+------+-----+---------+----------------+
| Field     | Type        | Null | Key | Default | Extra          |
+-----------+-------------+------+-----+---------+----------------+
| id        | int(11)     | NO   | PRI | NULL    | auto_increment |
| date      | datetime    | NO   |     | NULL    |                |
| duration  | time        | NO   |     | NULL    |                |
| type      | int(11)     | NO   |     | NULL    |                |
+-----------+-------------+------+-----+---------+----------------+

+-------+---------------------+----------+------+
| id    | date                | duration | type |
+-------+---------------------+----------+------+
|   1   | 2013-12-10 10:00:00 | 02:00:00 |    0 |
|   2   | 2013-12-11 10:00:00 | 02:00:00 |    0 |
+-------+---------------------+----------+------+

- 活动

+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int(11)     | NO   | PRI | NULL    | auto_increment |
| begin       | datetime    | NO   |     | NULL    |                |
| end         | datetime    | YES  |     | NULL    |                |
| break       | tinyint(1)  | NO   |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+

+----+---------------------+---------------------+-------+
| id | begin               | end                 | break |
+----+---------------------+---------------------+-------+
|  1 | 2013-12-10 00:00:00 | 2013-12-11 23:59:00 |     1 |
+----+---------------------+---------------------+-------+

-course_grade

+-----------+----------+
| course_id | grade_id |
+-----------+----------+
|     1     |       66 |
|     2     |       65 |
|     2     |       66 |
+-----------+----------+

-event_grade

+----------+----------+
| grade_id | event_id |
+----------+----------+
|       66 |        1 |
+----------+----------+

所以在这里,只有课程2应该出现,因为课程1只有一个年级,这个年级有一个事件。

2 个答案:

答案 0 :(得分:0)

  1. 我喜欢谜语,这是一个很好的,有很多解决方案,我想
  2. 如你所说'欢迎任何帮助',我会给出答案 altough 它不是解决方案(并且它不适合评论)
  3. 我不知道,如果你只是想要(A)裸体陈述(过去和过去),或者如果你想(B)了解如何找到解决方案,我会(B)
  4. 在开始解决方案之前,我先从'我会改变什么'开始:

    您正在混合datedatetimestartendduration,尝试仅使用一种逻辑(如果它是您的模型)即

    事件/课程有开始和结束时间(或开始/持续时间)

    持续时间应该(恕我直言)不是时间

    尝试找到事件/课程的最小时间片(是否有1秒事件?或者是5'的粒度(即10:00,10:05,10:10等)是否有效折衷?< / p>

    我的解决方案,一个不具学术性的prgmatic (听起来很有趣,但在我看到注释的simillar概率中确实有效)

    创建一个表格(T_TIME_OF_DAY),其中包含所有从00:00,00:05,... 23:55

    在有效且有用的范围内创建一个表(T_DAYS)(一年?)

    如果您需要查看整整一年(和{&lt;> >>,请将它们称为时间点(即select date, time from T_DAYS,T_TIME_OF_DAY无条件) - (天x次)300 * 24 * 12~100,000行5'对你来说没问题) - 那不是很多而且没有问题

    下一步是加入适合你时间点的诅咒(并且行数降至&lt;&lt;&lt; 100.000)

    如果你接下来将这些与你的活动加入(再次使用时间点),你应该得到你想要的。

        simplyfied quarters of a day:
    
                    12  12  12  12  12  12  12  12  
                    08  09  10  11  12  13  14  15  
                    |...|...|...|...|...|...|...|...
        grade 65 (C).............2..................
        grade 66 (C).........1...2..................
        grade 65 (E)................................
        grade 66 (e)........1111..................
    

    (注释:我使用这个逻辑来计算服务的可用性,关于他们每月/每年的停机时间,并且可以使用已经在时间点准备的数据进行显示)

答案 1 :(得分:0)

(第二个答案,因为它是一个完全不同的mor3标准方法)

我为你做了SQLFiddle

所以该怎么做:

那是一个解决方案:

第一步(记住)选择课程,成绩(让我们称之为C)

第二步(记住)选择事件,成绩(让我们称之为E)

和 - tada -

从C中选择全部,其中E中没有行具有相同的成绩和相同的日期(不知何故)和eventtype ='break'

所以你的解决方案:

    select 
    id, date start_time, date+duration end_time, grade_id 
    from Course c join course_grade cg on c.id=cg.course_id 
    where not exists ( 
    select grade_id, begin start_time, end end_time 
    from event_grade eg join event e on eg.event_id=e.id
    where 
      eg.grade_id=cg.grade_id
      and e.break=1
      and
       (
       (e.begin<=c.date and e.end >=c.date+c.duration)
       or e.begin between c.date and c.date+c.duration
       or e.end between c.date and c.date+c.duration
       )    

    ) 

我没注意优化这里