1,8,2011-06-12 12:13:13
1,8,2011-06-12 12:14:13
1,9,2011-06-12 13:11:13
1,8,2011-06-12 14:23:23
2,3,2011-06-12 15:12:12
希望得到如下结果:
id,status,min(time),max(time)
1,8,2011-06-12 12:13:13,2011-06-12 12:14:13
1,9,2011-06-12 13:11:13, 2011-06-12 13:11:13
1,8,2011-06-12 14:23:23, 2011-06-12 14:23:23
2,3,2011-06-12 15:12:12, 2011-06-12 15:12:12
下面的sql语句得到的却不是这个结果
sql语句:
select id,status,min(time),max(time) from temp group by id,status order by time;
结果:
id,status,min(time),max(time)
1,8,2011-06-12 12:13:13,2011-06-12 14:23:23
1,9,2011-06-12 13:11:13, 2011-06-12 13:11:13
2,3,2011-06-12 15:12:12, 2011-06-12 15:12:12
这个结果是先分组然后排序的,怎么才能得到希望的结果呢先排序后分组。
27 个解决方案
#1
你期望的结果完全不知道是按什么分的组
#2
不知道你想期望什么,你最起码告诉别人你的逻辑
#3
即使先排序后分组,按id,status分组后的记录也和你上面的错误结果一样的。
要想得到你想要的正确结果,同时按照id,status,time(针对你的数据,time分组时要截取到月,即按年月分组,
去掉时间)分组,就是你想要的结果
要想得到你想要的正确结果,同时按照id,status,time(针对你的数据,time分组时要截取到月,即按年月分组,
去掉时间)分组,就是你想要的结果
#4
没有其他的方法吗?这个例子是可以把时间截取到月,但是我的项目中用到的时间最小是到秒,有没有更好的方法。
#5
详细说明,格式是否固定 ,两列时间相差1秒?没有唯一标识的字段?
#6
SELECT id,STATUS,MIN(TIME),MAX(TIME) FROM
(
SELECT id,STATUS,TIME,(SELECT COUNT(*) FROM temp b WHERE b.time<=a.time) cnt1,
(SELECT COUNT(*) FROM temp c WHERE c.time>=a.time AND a.id=c.id AND a.`status`=c.status)cnt2
FROM temp a
) d
GROUP BY id,STATUS,cnt1+cnt2
ORDER BY MIN(TIME);
#7
mysql> SELECT * FROM temp;
+------+--------+---------------------+
| id | STATUS | TIME |
+------+--------+---------------------+
| 1 | 8 | 2011-06-12 12:14:13 |
| 1 | 9 | 2011-06-12 13:11:13 |
| 1 | 8 | 2011-06-12 14:23:23 |
| 2 | 3 | 2011-06-12 15:12:12 |
| 1 | 8 | 2011-06-12 12:13:13 |
+------+--------+---------------------+
5 ROWS IN SET (0.00 sec)
mysql> SELECT id,STATUS,MIN(TIME),MAX(TIME) FROM
-> (
-> SELECT id,STATUS,TIME,(SELECT COUNT(*) FROM temp b WHERE b.time<=a.time)
cnt1,
-> (SELECT COUNT(*) FROM temp c WHERE c.time>=a.time A
ND a.id=c.id AND a.`status`=c.status)cnt2
-> FROM temp a
-> ) d
-> GROUP BY id,STATUS,cnt1+cnt2
-> ORDER BY MIN(TIME);
+------+--------+---------------------+---------------------+
| id | STATUS | MIN(TIME) | MAX(TIME) |
+------+--------+---------------------+---------------------+
| 1 | 8 | 2011-06-12 12:13:13 | 2011-06-12 12:14:13 |
| 1 | 9 | 2011-06-12 13:11:13 | 2011-06-12 13:11:13 |
| 1 | 8 | 2011-06-12 14:23:23 | 2011-06-12 14:23:23 |
| 2 | 3 | 2011-06-12 15:12:12 | 2011-06-12 15:12:12 |
+------+--------+---------------------+---------------------+
4 ROWS IN SET (0.01 sec)
mysql>
#8
看楼主的意思应该是仅对时间上相邻,并且id和stauts相同的数据进行分组,要做到这点,就必须先对数据进行排序.
首先按时间进行排序得到所有数据的时间序号,再对同id及status的数据按时间进行逆向排序,再使用id,status,两个序号的和进行分组,就可以得到数据.
首先按时间进行排序得到所有数据的时间序号,再对同id及status的数据按时间进行逆向排序,再使用id,status,两个序号的和进行分组,就可以得到数据.
#9
谢谢楼上的朋友,方法可以用,但是数据量大花费的时间就太长了。我打算用存储过程,希望能减少花费的时间。
#10
1,8,2011-06-12 12:13:13
1,8,2011-06-12 12:14:13
1,8,2011-06-12 12:15:13
1,9,2011-06-12 13:11:13
1,8,2011-06-12 14:23:23
2,3,2011-06-12 15:12:12
这种情况如何处理
1,8,2011-06-12 12:14:13
1,8,2011-06-12 12:15:13
1,9,2011-06-12 13:11:13
1,8,2011-06-12 14:23:23
2,3,2011-06-12 15:12:12
这种情况如何处理
#11
如果支持分析函数的话估计会快点.
#12
10楼得什么意思
能不能用存储过程来完成呢?这是我的一个想法,不过我对写存储过程没有用过不会写。
能不能用存储过程来完成呢?这是我的一个想法,不过我对写存储过程没有用过不会写。
#13
不见的会快.
你可以测试下.
建议在time列建个索引.
你可以测试下.
建议在time列建个索引.
#14
如果是这样的记录,要求结果是什么
#15
结果:
1,8,2011-06-12 12:13:13,2011-06-12 12:15:13
1,9,2011-06-12 13:11:13,2011-06-12 13:11:13
1,8,2011-06-12 14:23:23,2011-06-12 14:23:23
2,3,2011-06-12 15:12:12,2011-06-12 15:12:12
#16
SET @a=0;
SET @num=0;
SELECT id,`status`,bz,MAX(`time`),MIN(`time`) FROM (
SELECT *,@num:=IF(@a=`status`,@num,@num+1) AS bz,@a:=`status` FROM qqw) a GROUP BY id,`status`,bz;
SET @num=0;
SELECT id,`status`,bz,MAX(`time`),MIN(`time`) FROM (
SELECT *,@num:=IF(@a=`status`,@num,@num+1) AS bz,@a:=`status` FROM qqw) a GROUP BY id,`status`,bz;
#17
能解释一下这个语句的意思吗?
#18
哪个地方不明白
#19
我看了半天没看懂LZ要什么,
貌似不是分组排序的问题,还涉及status字段的判断吧。
按照分组和排序的做法,我只能得到:
ID;"STATUS";"MIN(TIME)";"MAX(TIME)"
======================================
1;"8";"2011-06-12 12:13:13";"2011-06-12 14:23:23"
2;"3";"2011-06-12 15:12:12";"2011-06-12 15:12:12"
我的SQL
[SQL]
SELECT * FROM TEMP;
SELECT T1.ID ,T1.`STATUS`,T1.`TIME` AS `MIN(TIME)` ,T2.`TIME` AS `MAX(TIME)`
FROM (select * from TEMP WHERE (id,`time`) in (select id,min(`time`) from TEMP group by id)) T1,
(select * from TEMP WHERE (id,`time`) in (select id,max(`time`) from TEMP group by id)) T2
WHERE T1.ID = T2.ID;
[/SQL]
貌似不是分组排序的问题,还涉及status字段的判断吧。
按照分组和排序的做法,我只能得到:
ID;"STATUS";"MIN(TIME)";"MAX(TIME)"
======================================
1;"8";"2011-06-12 12:13:13";"2011-06-12 14:23:23"
2;"3";"2011-06-12 15:12:12";"2011-06-12 15:12:12"
我的SQL
[SQL]
SELECT * FROM TEMP;
SELECT T1.ID ,T1.`STATUS`,T1.`TIME` AS `MIN(TIME)` ,T2.`TIME` AS `MAX(TIME)`
FROM (select * from TEMP WHERE (id,`time`) in (select id,min(`time`) from TEMP group by id)) T1,
(select * from TEMP WHERE (id,`time`) in (select id,max(`time`) from TEMP group by id)) T2
WHERE T1.ID = T2.ID;
[/SQL]
#20
SET @a=0;
SET @num=0;
SELECT id,`status`,bz,MAX(`time`),MIN(`time`) FROM (
SELECT *,@num:=IF(@a=`status`,@num,@num+1) AS bz,@a:=`status` FROM qqw) a GROUP BY id,`status`,bz;
这个语句为什么不能再mysql中执行呢,@num:=IF(@a=`status`,@num,@num+1) AS bz,@a:=`status` FROM qqw这是什么意思。
怎么能运行这个语句。
#21
在SP中运行
OR
在MYSQL命令行下运行
OR
在MYSQL命令行下运行
#22
我是要在程序代码中使用的,但是不能用,哎。
大家帮忙看看有没有更好的方法解决问题呢。
#23
你生成SP,在代码中调用不行?
#24
我冒昧的问一下,sp是什么,怎么生成啊。
#25
存储过程
#26
先排序,后分组
SELECT * FROM (SELECT name, value FROM table ORDER BY value ASC) AS O GROUP BY O.name
=_=...
SELECT * FROM (SELECT name, value FROM table ORDER BY value ASC) AS O GROUP BY O.name
=_=...
#27
这个是先排序后分组,很简单,但是实现不了我要的结果。
#1
你期望的结果完全不知道是按什么分的组
#2
不知道你想期望什么,你最起码告诉别人你的逻辑
#3
即使先排序后分组,按id,status分组后的记录也和你上面的错误结果一样的。
要想得到你想要的正确结果,同时按照id,status,time(针对你的数据,time分组时要截取到月,即按年月分组,
去掉时间)分组,就是你想要的结果
要想得到你想要的正确结果,同时按照id,status,time(针对你的数据,time分组时要截取到月,即按年月分组,
去掉时间)分组,就是你想要的结果
#4
没有其他的方法吗?这个例子是可以把时间截取到月,但是我的项目中用到的时间最小是到秒,有没有更好的方法。
#5
详细说明,格式是否固定 ,两列时间相差1秒?没有唯一标识的字段?
#6
SELECT id,STATUS,MIN(TIME),MAX(TIME) FROM
(
SELECT id,STATUS,TIME,(SELECT COUNT(*) FROM temp b WHERE b.time<=a.time) cnt1,
(SELECT COUNT(*) FROM temp c WHERE c.time>=a.time AND a.id=c.id AND a.`status`=c.status)cnt2
FROM temp a
) d
GROUP BY id,STATUS,cnt1+cnt2
ORDER BY MIN(TIME);
#7
mysql> SELECT * FROM temp;
+------+--------+---------------------+
| id | STATUS | TIME |
+------+--------+---------------------+
| 1 | 8 | 2011-06-12 12:14:13 |
| 1 | 9 | 2011-06-12 13:11:13 |
| 1 | 8 | 2011-06-12 14:23:23 |
| 2 | 3 | 2011-06-12 15:12:12 |
| 1 | 8 | 2011-06-12 12:13:13 |
+------+--------+---------------------+
5 ROWS IN SET (0.00 sec)
mysql> SELECT id,STATUS,MIN(TIME),MAX(TIME) FROM
-> (
-> SELECT id,STATUS,TIME,(SELECT COUNT(*) FROM temp b WHERE b.time<=a.time)
cnt1,
-> (SELECT COUNT(*) FROM temp c WHERE c.time>=a.time A
ND a.id=c.id AND a.`status`=c.status)cnt2
-> FROM temp a
-> ) d
-> GROUP BY id,STATUS,cnt1+cnt2
-> ORDER BY MIN(TIME);
+------+--------+---------------------+---------------------+
| id | STATUS | MIN(TIME) | MAX(TIME) |
+------+--------+---------------------+---------------------+
| 1 | 8 | 2011-06-12 12:13:13 | 2011-06-12 12:14:13 |
| 1 | 9 | 2011-06-12 13:11:13 | 2011-06-12 13:11:13 |
| 1 | 8 | 2011-06-12 14:23:23 | 2011-06-12 14:23:23 |
| 2 | 3 | 2011-06-12 15:12:12 | 2011-06-12 15:12:12 |
+------+--------+---------------------+---------------------+
4 ROWS IN SET (0.01 sec)
mysql>
#8
看楼主的意思应该是仅对时间上相邻,并且id和stauts相同的数据进行分组,要做到这点,就必须先对数据进行排序.
首先按时间进行排序得到所有数据的时间序号,再对同id及status的数据按时间进行逆向排序,再使用id,status,两个序号的和进行分组,就可以得到数据.
首先按时间进行排序得到所有数据的时间序号,再对同id及status的数据按时间进行逆向排序,再使用id,status,两个序号的和进行分组,就可以得到数据.
#9
谢谢楼上的朋友,方法可以用,但是数据量大花费的时间就太长了。我打算用存储过程,希望能减少花费的时间。
#10
1,8,2011-06-12 12:13:13
1,8,2011-06-12 12:14:13
1,8,2011-06-12 12:15:13
1,9,2011-06-12 13:11:13
1,8,2011-06-12 14:23:23
2,3,2011-06-12 15:12:12
这种情况如何处理
1,8,2011-06-12 12:14:13
1,8,2011-06-12 12:15:13
1,9,2011-06-12 13:11:13
1,8,2011-06-12 14:23:23
2,3,2011-06-12 15:12:12
这种情况如何处理
#11
如果支持分析函数的话估计会快点.
#12
10楼得什么意思
能不能用存储过程来完成呢?这是我的一个想法,不过我对写存储过程没有用过不会写。
能不能用存储过程来完成呢?这是我的一个想法,不过我对写存储过程没有用过不会写。
#13
不见的会快.
你可以测试下.
建议在time列建个索引.
你可以测试下.
建议在time列建个索引.
#14
如果是这样的记录,要求结果是什么
#15
结果:
1,8,2011-06-12 12:13:13,2011-06-12 12:15:13
1,9,2011-06-12 13:11:13,2011-06-12 13:11:13
1,8,2011-06-12 14:23:23,2011-06-12 14:23:23
2,3,2011-06-12 15:12:12,2011-06-12 15:12:12
#16
SET @a=0;
SET @num=0;
SELECT id,`status`,bz,MAX(`time`),MIN(`time`) FROM (
SELECT *,@num:=IF(@a=`status`,@num,@num+1) AS bz,@a:=`status` FROM qqw) a GROUP BY id,`status`,bz;
SET @num=0;
SELECT id,`status`,bz,MAX(`time`),MIN(`time`) FROM (
SELECT *,@num:=IF(@a=`status`,@num,@num+1) AS bz,@a:=`status` FROM qqw) a GROUP BY id,`status`,bz;
#17
能解释一下这个语句的意思吗?
#18
哪个地方不明白
#19
我看了半天没看懂LZ要什么,
貌似不是分组排序的问题,还涉及status字段的判断吧。
按照分组和排序的做法,我只能得到:
ID;"STATUS";"MIN(TIME)";"MAX(TIME)"
======================================
1;"8";"2011-06-12 12:13:13";"2011-06-12 14:23:23"
2;"3";"2011-06-12 15:12:12";"2011-06-12 15:12:12"
我的SQL
[SQL]
SELECT * FROM TEMP;
SELECT T1.ID ,T1.`STATUS`,T1.`TIME` AS `MIN(TIME)` ,T2.`TIME` AS `MAX(TIME)`
FROM (select * from TEMP WHERE (id,`time`) in (select id,min(`time`) from TEMP group by id)) T1,
(select * from TEMP WHERE (id,`time`) in (select id,max(`time`) from TEMP group by id)) T2
WHERE T1.ID = T2.ID;
[/SQL]
貌似不是分组排序的问题,还涉及status字段的判断吧。
按照分组和排序的做法,我只能得到:
ID;"STATUS";"MIN(TIME)";"MAX(TIME)"
======================================
1;"8";"2011-06-12 12:13:13";"2011-06-12 14:23:23"
2;"3";"2011-06-12 15:12:12";"2011-06-12 15:12:12"
我的SQL
[SQL]
SELECT * FROM TEMP;
SELECT T1.ID ,T1.`STATUS`,T1.`TIME` AS `MIN(TIME)` ,T2.`TIME` AS `MAX(TIME)`
FROM (select * from TEMP WHERE (id,`time`) in (select id,min(`time`) from TEMP group by id)) T1,
(select * from TEMP WHERE (id,`time`) in (select id,max(`time`) from TEMP group by id)) T2
WHERE T1.ID = T2.ID;
[/SQL]
#20
SET @a=0;
SET @num=0;
SELECT id,`status`,bz,MAX(`time`),MIN(`time`) FROM (
SELECT *,@num:=IF(@a=`status`,@num,@num+1) AS bz,@a:=`status` FROM qqw) a GROUP BY id,`status`,bz;
这个语句为什么不能再mysql中执行呢,@num:=IF(@a=`status`,@num,@num+1) AS bz,@a:=`status` FROM qqw这是什么意思。
怎么能运行这个语句。
#21
在SP中运行
OR
在MYSQL命令行下运行
OR
在MYSQL命令行下运行
#22
我是要在程序代码中使用的,但是不能用,哎。
大家帮忙看看有没有更好的方法解决问题呢。
#23
你生成SP,在代码中调用不行?
#24
我冒昧的问一下,sp是什么,怎么生成啊。
#25
存储过程
#26
先排序,后分组
SELECT * FROM (SELECT name, value FROM table ORDER BY value ASC) AS O GROUP BY O.name
=_=...
SELECT * FROM (SELECT name, value FROM table ORDER BY value ASC) AS O GROUP BY O.name
=_=...
#27
这个是先排序后分组,很简单,但是实现不了我要的结果。