将mySQL子查询更改为联接以提高效率
为了提高效率,是否可以将下面的mySQL查询更改为使用联接而不是子查询,或者以其他方式提高效率?我有一张病人去急诊室的桌子。该表列出了到达和离开时间。我需要这个查询来返回患者到达时已经在急诊科就诊的患者总数 我的桌子看起来像这样:将mySQL子查询更改为联接以提高效率,mysql,subquery,Mysql,Subquery,为了提高效率,是否可以将下面的mySQL查询更改为使用联接而不是子查询,或者以其他方式提高效率?我有一张病人去急诊室的桌子。该表列出了到达和离开时间。我需要这个查询来返回患者到达时已经在急诊科就诊的患者总数 我的桌子看起来像这样: +------+------+---------------------+---------------------+ | id | name | arrival | departure | +------+------
+------+------+---------------------+---------------------+
| id | name | arrival | departure |
+------+------+---------------------+---------------------+
| 1 | Joe | 2010-01-01 00:00:00 | 2010-01-01 02:00:00 |
| 2 | John | 2010-01-01 00:05:00 | 2010-01-01 03:00:00 |
| 3 | Jane | 2010-01-01 01:00:00 | 2010-01-01 04:00:00 |
...
+------+--------+
| name | census |
+------+--------+
| Joe | 0 |
| John | 1 |
| Jane | 2 |
...
结果如下:
+------+------+---------------------+---------------------+
| id | name | arrival | departure |
+------+------+---------------------+---------------------+
| 1 | Joe | 2010-01-01 00:00:00 | 2010-01-01 02:00:00 |
| 2 | John | 2010-01-01 00:05:00 | 2010-01-01 03:00:00 |
| 3 | Jane | 2010-01-01 01:00:00 | 2010-01-01 04:00:00 |
...
+------+--------+
| name | census |
+------+--------+
| Joe | 0 |
| John | 1 |
| Jane | 2 |
...
下面的查询可以工作,但在180000行上相当慢,大约3.5秒。有没有办法通过某种连接或其他方法来提高此查询的效率
select name, arrival,
(SELECT count(*)
FROM patient_arrivals as b
WHERE b.arrival <= a.arrival and b.departure >= a.departure) as census
FROM patient_arrivals as a
我不认为加入会有帮助。相反,您需要重新构造查询。以下是任何特定时间房间内的患者人数:
select t, sum(num) as num, @total := @total + num as total
from (select arrival as t, 1 as num
from patient_arrivals
union all
select departure, -1
from patient_arrivals
) t cross join
(select @total := 0) vars
group by t
order by t
然后,您可以将其用作联接的子查询:
select pa.*, t.total as census
from patient_arrivals pa join
(select t, sum(num) as num, @total := @total + num as total
from (select arrival as t, 1 as num
from patient_arrivals
union all
select departure, -1
from patient_arrivals
) t cross join
(select @total := 0) vars
group by t
order by t
) tnum
on pa.arrival = tnum.t;
这将给出患者到达时的编号。对于重叠的总数:
select pa.*, max(t.total) as census
from patient_arrivals pa join
(select t, sum(num) as num, @total := @total + num as total
from (select arrival as t, 1 as num
from patient_arrivals
union all
select departure, -1
from patient_arrivals
) t cross join
(select @total := 0) vars
group by t
order by t
) tnum
on tnum.t between pa.arrival and pa.departure
group by pa.id