I got a problem with limiting left join, what I want is to every row in first table get only one result from second table.
Here is my code without limiting:
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)
)
I also tried to limit it, but then I get only one correct result:
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)
)
Below example of table:
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
And expected result:
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
Thanks in advance
EDIT:
To clarify, my query (1st one) is working but it gives more result than I want, so I need only to limit it to get only one row from 2nd table of left join. So to every row from
(SELECT id,date as end,machine_id,numer FROM `order_log` WHERE typ = 1)
I want to get one and only one row from
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)
I need to get all existing pairs, but I am sure that if end exists begin also exists, that's why I search for all typ='1'(end) first.
Below the result I got right now to compare with expected one:
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
2nd row is unwanted
First, don't over use subqueries in MySQL. So, write the query as:
(I think this is equivalent.) The subqueries add additional overhead for materialization (only in MySQL, other databases do the right thing). And, they tend to prevent the use of indexes.
However, you seem to want the most recent pair of starts and stops. With your data structure, it is a bit painful to get this using
join
s. Instead, for each row, count the number of stops that appear afterwards for a given machine/numer combination. Then simply take the rows that have a value of "1" and use conditional aggregation: