Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 为钙化日期时间差优化查询_Mysql_Sql - Fatal编程技术网

Mysql 为钙化日期时间差优化查询

Mysql 为钙化日期时间差优化查询,mysql,sql,Mysql,Sql,我有一个SQL表: +---------+----------+---------------------+---------------------+---------+ | id | party_id | begintime | endtime | to_meas | +---------+----------+---------------------+---------------------+---------+ | 1395035

我有一个SQL表:

+---------+----------+---------------------+---------------------+---------+
| id      | party_id | begintime           | endtime             | to_meas |
+---------+----------+---------------------+---------------------+---------+
| 1395035 |     9255 | 2010-09-26 00:34:02 | 2010-09-26 03:56:20 |       0 |
| 1395036 |     8974 | 2009-07-10 11:00:00 | 2009-07-10 21:30:00 |       0 |
| 1395037 |     8974 | 2009-07-10 23:14:00 | 2009-07-11 08:48:00 |       0 |
| 1395038 |     8975 | 2009-07-10 11:00:00 | 2009-07-10 21:30:00 |       0 |
| 1395039 |     8975 | 2009-07-10 23:14:00 | 2009-07-11 08:48:00 |       0 |
| 1395040 |     8974 | 2009-07-11 10:08:31 | 2009-07-12 18:49:51 |       0 |
| 1395041 |     8975 | 2009-07-11 10:08:31 | 2009-07-12 18:49:51 |       0 |
| 1395042 |     8974 | 2009-07-12 20:38:27 | 2009-07-13 20:33:21 |       0 |
| 1395043 |     8975 | 2009-07-12 20:38:27 | 2009-07-13 20:33:21 |       0 |
| 1395044 |     8974 | 2009-07-13 21:57:37 | 2009-07-15 08:25:45 |       0 |
| 1395045 |     8975 | 2009-07-13 21:57:37 | 2009-07-15 08:25:45 |       0 |
| 1395046 |     8974 | 2009-07-15 08:51:25 | 2009-07-16 10:29:13 |       0 |
| 1395047 |     8975 | 2009-07-15 08:51:25 | 2009-07-16 10:29:13 |       0 |
| 1395048 |     8974 | 2009-07-16 12:22:22 | 2009-07-17 14:39:10 |       0 |
| 1395049 |     8975 | 2009-07-16 12:22:22 | 2009-07-17 14:39:10 |       0 |
| 1395050 |     8976 | 2009-07-24 16:53:48 | 2009-07-25 08:47:29 |       0 |
| 1395051 |     8977 | 2009-07-24 16:53:48 | 2009-07-25 08:47:29 |       0 |
| 1395052 |     8978 | 2009-07-24 16:53:48 | 2009-07-25 08:47:29 |       0 |
| 1395053 |     8979 | 2009-07-24 16:53:48 | 2009-07-25 08:47:29 |       0 |
| 1395054 |     8976 | 2009-07-25 10:47:14 | 2009-07-26 09:41:44 |       0 |
+---------+----------+---------------------+---------------------+---------+
...
我需要计算begintime和previous endtime之间的时间,如果此差值大于30分钟,则将_meas设置为1。以下是我在MySQL中的尝试:

update doses d set to_meas=1 where d.id in 
  (select a.id from party join (select * from doses) a 
  on party_id=a.party_id 
  left join (select * from doses) b 
  on party.id=b.party_id 
  and b.begintime=(select min(begintime) 
  from (select * from doses) c 
  where c.begintime > a.endtime) 
  and timestampdiff(minute, a.endtime, b.begintime) > 30 
  group by party.id);
此命令准永久运行。我曾尝试在python的pandas中这样做:

最后一条语句大约运行10秒。有没有一种方法可以优化SQL代码,使其运行速度与pandas'one一样快?

在MySQL 8.0中,您可以使用窗口函数选择想要的结果,如下所示:

select d.*,
    (begintime > lag(endtime) over(partition by pary_id order by endtime) + interval 30 minute) as to_meas
from doses d
在早期版本中:

select d.*,
    (
        begintime > (
            select max(endtime) + interval 30 minute
            from doses d1
            where d1.party_id = d.party_id and d1.endtime < d.endtime
        )
    ) as to_meas
from doses d
在MySQL 8.0中,您可以通过窗口函数选择想要的结果,如下所示:

select d.*,
    (begintime > lag(endtime) over(partition by pary_id order by endtime) + interval 30 minute) as to_meas
from doses d
在早期版本中:

select d.*,
    (
        begintime > (
            select max(endtime) + interval 30 minute
            from doses d1
            where d1.party_id = d.party_id and d1.endtime < d.endtime
        )
    ) as to_meas
from doses d

您可以使用exists更新数据,如下所示:

Update doses d
   Set meas = 1
 Where begintime > (select max(dd.endtime) + interval '30' minute 
From doses dd where dd.begintime < d.begintime
  And dd.party_id = d.party_id)

您可以使用exists更新数据,如下所示:

Update doses d
   Set meas = 1
 Where begintime > (select max(dd.endtime) + interval '30' minute 
From doses dd where dd.begintime < d.begintime
  And dd.party_id = d.party_id)

如果要更新数据,可以在更新中使用窗口函数:

然后,对于这个查询,您需要一个关于doseParty_id endtime的索引。我假设id已经声明为主键

注意:使用此索引,您可能会发现只需动态计算值比将其存储在表中更快

编辑:

在MySQL的旧版本中,您可以将其表述为:

update doses d join
       (select d.*, 
               (select d2.endtime
                from doses d2
                where d2.party_id = d.party_id and
                      d2.endtime < d.endtime
               ) as prev_endtime
        from doses d
       ) dd
       on d.id = dd.id and
          d.starttime > dd.prev_endtime + interval 30 minute
    set to_meas = 1;

每个party_id的行数相对较少,因此相关查询似乎是合理的。这还需要一个关于party_id,endtime的索引。

如果要更新数据,可以在更新中使用窗口功能:

然后,对于这个查询,您需要一个关于doseParty_id endtime的索引。我假设id已经声明为主键

注意:使用此索引,您可能会发现只需动态计算值比将其存储在表中更快

编辑:

在MySQL的旧版本中,您可以将其表述为:

update doses d join
       (select d.*, 
               (select d2.endtime
                from doses d2
                where d2.party_id = d.party_id and
                      d2.endtime < d.endtime
               ) as prev_endtime
        from doses d
       ) dd
       on d.id = dd.id and
          d.starttime > dd.prev_endtime + interval 30 minute
    set to_meas = 1;

每个party_id的行数相对较少,因此相关查询似乎是合理的。这还需要一个关于party_id,endtime的索引。

MySQL不支持在相关子查询中重新打开update语句的目标表,因此此查询引发语法错误:。这是MySQL更新语法的一个典型限制。@GMB这里应该和我一样:。。。From select*From dd…MySQL不支持在相关子查询中重新打开update语句的目标表,因此此查询引发语法错误:。这是MySQL更新语法的一个典型限制。@GMB这里应该和我一样:。。。从select*From DOVES dd…OP在我的回答中的某个点上评论说他们正在运行MySQL 5.7。但是这个评论被删除了。是的,我有5.7 OP在我的回答中的某个点上评论了他们运行的是MySQL 5.7。不过,该评论已被删除。是的,我有5.7