假设我已经给出startTime
和endTime
,并且这些间隔是半小时。例如startTime=8:00
,endTime=12:00
所以可能的时间是8:00, 8:30, 9:00, 9:30, 10:00, 10:30, 11:00, 11:30, 12:00
现在我有一系列动作,其中包含我的动作发生的时间段。每行都有rowStartTime和rowEndTime。 它们的类型为TIME
我想要实现的是按时间返回GROUPed结果,并在该特定时间内发生行数。
演示数据
name rowStarTime rowEndTime
--------------------------------
action1 6:00 10:00
action2 9:00 13:00
action3 10:00 11:30
action4 12:00 13:00
action5 11:30 15:00
预期结果
Time Action count (actions in that time, this is just comment)
---------------------------------------------------------------------
8:00 1 //1
8:30 1 //1
9:00 2 //1, 2
9:30 2 //1, 2
10:00 3 //1, 2, 3
10:30 2 //2, 3
11:00 2 //2, 3
11:30 3 //2, 3, 5
12:00 4 //2, 4, 5
我想在数据库级别(使用SQL)上充分利用它。它可行吗?或者我必须得到一些PHP的帮助(我使用的是Doctrine DQL,但我可以使用许多特殊的SQL函数https://github.com/orocrm/doctrine-extensions& https://github.com/beberlei/DoctrineExtensions)?
我只能为rowStartTime
实现这一目标,而不是整个时期:
SELECT `rowStartTime` AS sclr_0, COUNT(o.id) AS sclr_1
FROM orders o
GROUP BY sclr_0
(如果仅在startTime
和endTime
之间选择时间会使其变得困难,那么它不是核心,可以省略此条件)
答案 0 :(得分:2)
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(name VARCHAR(12) NOT NULL PRIMARY KEY
,start_time TIME NOT NULL
,end_time TIME NOT NULL
);
INSERT INTO my_table VALUES
('action1', '6:00:00','10:00:00'),
('action2', '9:00:00','13:00:00'),
('action3','10:00:00','11:30:00'),
('action4','12:00:00','13:00:00'),
('action5','11:30:00','15:00:00');
SELECT * FROM my_table;
+---------+------------+----------+
| name | start_time | end_time |
+---------+------------+----------+
| action1 | 06:00:00 | 10:00:00 |
| action2 | 09:00:00 | 13:00:00 |
| action3 | 10:00:00 | 11:30:00 |
| action4 | 12:00:00 | 13:00:00 |
| action5 | 11:30:00 | 15:00:00 |
+---------+------------+----------+
SELECT * FROM ints;
+---+
| i |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+---+
SELECT SEC_TO_TIME(1800*(i2.i*10+i1.i)) time
, COUNT(*) total
, GROUP_CONCAT(x.name) actions
FROM ints i1
CROSS
JOIN ints i2
LEFT
JOIN my_table x
ON SEC_TO_TIME(1800*(i2.i*10+i1.i)) BETWEEN x.start_time AND x.end_time
WHERE SEC_TO_TIME(1800*(i2.i*10+i1.i)) BETWEEN '08:00:00' AND '12:00:00'
GROUP
BY time;
+----------+-------+-------------------------+
| time | total | actions |
+----------+-------+-------------------------+
| 08:00:00 | 1 | action1 |
| 08:30:00 | 1 | action1 |
| 09:00:00 | 2 | action1,action2 |
| 09:30:00 | 2 | action1,action2 |
| 10:00:00 | 3 | action1,action2,action3 |
| 10:30:00 | 2 | action2,action3 |
| 11:00:00 | 2 | action2,action3 |
| 11:30:00 | 3 | action2,action3,action5 |
| 12:00:00 | 3 | action2,action4,action5 |
+----------+-------+-------------------------+
答案 1 :(得分:1)
创建行动表
CREATE TABLE actions (a VARCHAR(50), start TIME, end TIME);
INSERT INTO actions (a,start,end) VALUES
('action 1', '6:00', '10:00'),
('action 2', '9:00', '13:00'),
('action 3', '10:00', '11:30'),
('action 4', '12:00', '13:00'),
('action 5', '11:30', '15:00');
创建时间表
CREATE TABLE times (t TIME);
INSERT INTO times (t) VALUES
('5:00'), ('5:30'),
('6:00'), ('6:30'),
('7:00'), ('7:30'),
('8:00'), ('8:30'),
('9:00'), ('9:30'),
('10:00'), ('10:30'),
('11:00'), ('11:30'),
('12:00'), ('12:30'),
('13:00'), ('13:30'),
('14:00'), ('14:30'),
('15:00'), ('15:30');
按时间选择
SELECT
times.t as t,
count(CASE WHEN actions.a IS NOT NULL THEN 1 ELSE NULL END) as c
FROM times
LEFT JOIN actions ON actions.start <= times.t AND actions.end >= times.t
GROUP BY times.t
结果
t c
05:00:00 0
05:30:00 0
06:00:00 1
06:30:00 1
07:00:00 1
07:30:00 1
08:00:00 1
08:30:00 1
09:00:00 2
09:30:00 2
10:00:00 3
10:30:00 2
11:00:00 2
11:30:00 3
12:00:00 3
12:30:00 3
13:00:00 3
13:30:00 1
14:00:00 1
14:30:00 1
15:00:00 1
15:30:00 0
答案 2 :(得分:1)
使用时间间隔创建临时表并使用
Time, count, actions
06:00:00, 1, action1
06:30:00, 1, action1
07:00:00, 1, action1
07:30:00, 1, action1
08:00:00, 1, action1
08:30:00, 1, action1
09:00:00, 2, action1,action2
09:30:00, 2, action1,action2
10:00:00, 3, action1,action2,action3
10:30:00, 2, action2,action3
11:00:00, 2, action2,action3
11:30:00, 3, action2,action3,action5
12:00:00, 3, action2,action4,action5
如您所见,结果
中不包括没有操作的时间public List<String> getAllPosts() {
pdb = this.getReadableDatabase();
List<String> postsList = new ArrayList<>();
String columns[] = {pid, post};
Cursor cursor = pdb.query(TABLE_NAME, columns, null, null, null, null, null);
cursor.moveToFirst();
Log.d("Cursor in pdb", DatabaseUtils.dumpCursorToString(cursor));
while(!cursor.isAfterLast()) {
int postIndex = cursor.getColumnIndex(post);
String post = cursor.getString(postIndex);
postsList.add(post);
cursor.moveToNext();
}
cursor.close();
return postsList;
}