Mysql - sql查询根据日期获取下一个类

时间:2015-03-21 08:35:50

标签: mysql sql

我在mysql数据库的webinar_timing表中有以下数据

start_time和end_time的类型为datetime


   id  | webinar_id | start_time            | end_time
-------------------------------------------------------------------
    1  |     5      | 3/18/2015  6:00:00 PM | 3/18/2015  7:00:00 PM
    2  |     5      | 3/19/2015  6:00:00 PM | 3/19/2015  7:00:00 PM
    3  |     5      | 3/20/2015  6:00:00 PM | 3/20/2015  7:00:00 PM
    4  |     5      | 3/21/2015  6:00:00 PM | 3/21/2015  7:00:00 PM
    5  |     5      | 3/22/2015  6:00:00 PM | 3/22/2015  7:00:00 PM
    6  |    11      | 3/20/2015  8:00:00 PM | 3/20/2015  9:00:00 PM
    7  |    11      | 3/21/2015  8:00:00 PM | 3/21/2015  9:00:00 PM
    8  |    11      | 3/22/2015  8:00:00 PM | 3/22/2015  9:00:00 PM
    9  |    22      | 3/25/2015  8:00:00 PM | 3/25/2015  9:00:00 PM
   10  |    22      | 3/27/2015  8:00:00 PM | 3/27/2015  9:00:00 PM
   11  |    22      | 3/29/2015  8:00:00 PM | 3/27/2015  9:00:00 PM

基本上,对于每个网络研讨会,我都希望完成或剩余的课程总数和课程数量以及NEXT即将开课的课程

Egs:当我运行此查询时,请在2015年3月21日下午4:00说 - 这是我期待的结果

 webinar_id | total     | Classes Completed | Next Class
----------------------------------------------------------
     5      |   5       | 3                 | 3/21/2015  6:00:00 PM
    11      |   3       | 1                 | 3/21/2015  8:00:00 PM
    22      |   3       | 0                 | 3/25/2015  8:00:00 PM

OR

 webinar_id | total     | Classes Remaining | Next Class
----------------------------------------------------------
     5      |   5       | 2                 | 3/21/2015  6:00:00 PM
    11      |   3       | 2                 | 3/21/2015  8:00:00 PM
    22      |   3       | 3                 | 3/25/2015  8:00:00 PM

基于前一个问题 - 一位SO Peter教授协助以下

select webinar_id, count(*) AS total, 
SUM(IF(end_time<NOW(), 1, 0)) AS completed, 
SUM(IF(start_time>=NOW(), 1, 0)) AS remaining
from webinar_times
group by webinar_id;

SQL小提琴 http://sqlfiddle.com/#!9/c4e71/1

任何帮助将不胜感激 提前致谢

3 个答案:

答案 0 :(得分:1)

类似的东西:

select webinar_id
     , count(*) AS total
     , count(case when end_time<NOW() then 1 end) as completed
     , (select count(1) 
        from webinar_times y
        where x.webinar_id = y.webinar_id
          and y.start_time > NOW()) as remaining
     , min(case when x.start_time > NOW() then x.start_time end) as next_class
from webinar_times x
group by webinar_id;

应该

编辑:意识到子选择是不必要的:

select webinar_id
     , count(*) AS total
     , count(case when end_time<NOW() then 1 end) as completed
     , count(case when start_time>NOW() then 1 end) as remaining  
     , min(case when x.start_time > NOW() then x.start_time end) as next_class     
from webinar_times x
group by webinar_id;

答案 1 :(得分:0)

您可以在两个分组查询之间建立外部联接,例如一个计算网络研讨会总数,另一个计算剩余网络研讨会数并获得下一个网络研讨会的开始时间:

SELECT * FROM (
    SELECT   webinar_id, COUNT(*) total
    FROM     webinar_times
    GROUP BY webinar_id
) totals NATURAL LEFT JOIN (
    SELECT   webinar_id, COUNT(*) remaining, MIN(start_time) next
    FROM     webinar_times
    WHERE    start_time > NOW()
    GROUP BY webinar_id
) future

sqlfiddle上看到它:

+------------+-------+-----------+-------------------------+
| webinar_id | total | remaining |                    next |
+------------+-------+-----------+-------------------------+
|          6 |     5 |         1 | March, 22 2015 06:00:00 |
|         11 |     3 |         1 | March, 22 2015 07:00:00 |
|         22 |     3 |         3 | March, 25 2015 07:00:00 |
+------------+-------+-----------+-------------------------+

(webinar_id, start_time)上定义的复合索引会使此查询受益,并避免在您的问题中概述的方法需要的全表扫描。

答案 2 :(得分:0)

请考虑以下示例,这将为您提供所需的内容

mysql> create table test (id int, webinar_id int, start_time datetime);
Query OK, 0 rows affected (0.16 sec)

mysql> insert into test values (1,5,'2015-03-18 18:00:00'),
  (2,5,'2015-03-19 18:00:00'),
  (3,5,'2015-03-20 18:00:00'),
  (4,5,'2015-03-21 18:00:00'),
  (5,5,'2015-03-21 18:00:00'),
  (6,11,'2015-03-20 20:00:00'),
  (7,11,'2015-03-21 20:00:00'),
  (8,11,'2015-03-22 20:00:00'),
  (9,22,'2015-03-25 20:00:00'),
  (10,22,'2015-03-27 20:00:00'),
  (11,22,'2015-03-29 20:00:00');
Query OK, 11 rows affected (0.05 sec)

Records: 11  Duplicates: 0  Warnings: 0

mysql> select * from test ;
+------+------------+---------------------+
| id   | webinar_id | start_time          |
+------+------------+---------------------+
|    1 |          5 | 2015-03-18 18:00:00 |
|    2 |          5 | 2015-03-19 18:00:00 |
|    3 |          5 | 2015-03-20 18:00:00 |
|    4 |          5 | 2015-03-21 18:00:00 |
|    5 |          5 | 2015-03-21 18:00:00 |
|    6 |         11 | 2015-03-20 20:00:00 |
|    7 |         11 | 2015-03-21 20:00:00 |
|    8 |         11 | 2015-03-22 20:00:00 |
|    9 |         22 | 2015-03-25 20:00:00 |
|   10 |         22 | 2015-03-27 20:00:00 |
|   11 |         22 | 2015-03-29 20:00:00 |
+------+------------+---------------------+
11 rows in set (0.00 sec)

select 
t.webinar_id, 
count(*) as total,
sum( case when t.start_time < now() then 1 else 0 end) as completed , 
sum( case when t.start_time > now() then 1 else 0 end) as remaining,
t1.next_date from test t 
join ( 
  select 
  webinar_id,
  min(start_time) as next_date 
  from test where start_time > now() 
  group by webinar_id 
)t1 on t.webinar_id= t1.webinar_id 
group by t.webinar_id;

+------------+-------+-----------+-----------+---------------------+
| webinar_id | total | completed | remaining | next_date           |
+------------+-------+-----------+-----------+---------------------+
|          5 |     5 |         3 |         2 | 2015-03-21 18:00:00 |
|         11 |     3 |         1 |         2 | 2015-03-21 20:00:00 |
|         22 |     3 |         0 |         3 | 2015-03-25 20:00:00 |
+------------+-------+-----------+-----------+---------------------+
3 rows in set (0.00 sec)