我遇到了限制左连接的问题,我想要的是第一个表中的每一行只得到第二个表中的一个结果。
这是我的代码,不受限制:
SELECT * FROM
(
((SELECT id,date as end,machine_id,numer FROM `order_log` WHERE typ = 1)STOP
left join
(SELECT date as begin, machine_id, numer FROM `order_log` ST WHERE typ = 0 ORDER BY date DESC)START
ON START.begin < STOP.end AND START.machine_id = STOP.machine_id
AND START.numer = STOP.numer)
)
我也试图限制它,但后来我只得到一个正确的结果:
SELECT * FROM
(
((SELECT id,date as end,machine_id,numer FROM `order_log` WHERE typ = 1)STOP
left join
(SELECT date as begin, machine_id, numer FROM `order_log` ST WHERE typ = 0 ORDER BY date DESC)START
ON START.begin = (SELECT date FROM `order_log` WHERE date < STOP.end AND typ = 0 AND machine_id = STOP.machine_id AND numer = STOP.numer ORDER BY date DESC LIMIT 1) AND START.machine_id = STOP.machine_id
AND START.numer = STOP.numer)
)
以下表格示例:
id numer machine_id typ date
1 31392 39 0 2015-05-26 15:44:56
2 31761 23 0 2015-05-26 16:12:53
3 31761 24 0 2015-05-26 16:14:03
4 31591 15 0 2015-05-26 16:15:02
5 31586 40 0 2015-05-26 16:15:46
6 31392 39 1 2015-05-26 16:16:19
7 31392 39 0 2015-05-26 16:16:19
8 31392 39 1 2015-05-28 08:15:26
9 31386 39 0 2015-05-28 08:15:26
10 31761 24 1 2015-06-02 00:40:07
11 31761 24 0 2015-06-02 00:40:07
12 31386 39 1 2015-06-02 13:11:13
13 31392 39 0 2015-06-02 13:11:13
预期结果:
id end machine_id numer begin machine_id numer
6 2015-05-26 16:16:19 39 31392 2015-05-26 15:44:56 39 31392
10 2015-06-02 00:40:07 24 31761 2015-05-26 16:14:03 24 31761
8 2015-05-28 08:15:26 39 31392 2015-05-26 16:16:19 39 31392
12 2015-06-02 13:11:13 39 31386 2015-05-28 08:15:26 39 31386
提前致谢
编辑:
为了澄清,我的查询(第一个)正在运行,但它提供的结果比我想要的多,所以我只需要限制它只从左连接的第二个表中获得一行。所以来自
的每一行(SELECT id,date as end,machine_id,numer FROM `order_log` WHERE typ = 1)
我想从
获得一行且只有一行left join
(SELECT date as begin, machine_id, numer FROM `order_log` ST WHERE typ = 0 ORDER BY date DESC)START
ON START.begin = (SELECT date FROM `order_log` WHERE date < STOP.end AND typ = 0 AND machine_id = STOP.machine_id AND numer = STOP.numer ORDER BY date DESC LIMIT 1) AND START.machine_id = STOP.machine_id
AND START.numer = STOP.numer)
我需要获得所有现有的对,但我确信如果结束存在也开始存在,这就是我首先搜索所有typ ='1'(结束)的原因。
我现在得到的结果与预期结果比较:
2015-05-26 16:16:19 39 31392 2015-05-26 15:44:56 39 31392
2015-05-28 08:15:26 39 31392 2015-05-26 15:44:56 39 31392
2015-06-02 00:40:07 24 31761 2015-05-26 16:14:03 24 31761
2015-05-28 08:15:26 39 31392 2015-05-26 16:16:19 39 31392
2015-06-02 13:11:13 39 31386 2015-05-28 08:15:26 39 31386
第二行是不需要的
答案 0 :(得分:0)
首先,不要在MySQL中使用子查询。因此,将查询写为:
SELECT s.id, s.date as end, s.machine_id, s.numer,
o.date as begin, o.machine_id, o.numer
FROM order_log s left join
order_log o
ON o.date < s.date AND o.machine_id = s.machine_id AND o.numer = s.numer
WHERE s.typ = 1 and o.typ = 0 ;
(我认为这是等价的。)子查询增加了实现的额外开销(仅在MySQL中,其他数据库做正确的事情)。并且,它们倾向于阻止使用索引。
但是,您似乎想要最近一对启动和停止。使用您的数据结构,使用join
来获取此信息会有点痛苦。相反,对于每一行,计算给定机器/数字组合的之后的停靠点数。然后只需获取值为&#34; 1&#34;的行。并使用条件聚合:
select machine_id, numer,
max(case when ol.typ = 1 then id end) as end_id,
max(case when ol.typ = 1 then date end) as end_date,
max(case when ol.typ = 0 then id end) as start_id,
max(case when ol.typ = 0 then date end) as start_date
from (select ol.*,
(select count(*)
from order_log ol2
where ol2.machine_id = ol.machine_id AND ol2.numer = ol.numer
) as grp
from orderlog ol
) ol
where grp = 1
group by machine_id, numer;