我在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
任何帮助将不胜感激 提前致谢
答案 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)