I tried a couple of times with different methods, but didn't got it working like it should be:
-- Main table (m1)
+-----+-----------+
| Cid | location |
+-----+-----------+
| 1 | Amsterdam |
| 2 | Berlin |
| 3 | Paris |
-- Info table 1 (i1)
+-----+-----+-------+------------------+
| id | Cid | light | date |
+-----+-----+-------+------------------+
| 995 | 1 | off | 10:30 22-09-2017 |
| 994 | 3 | on | 10:30 22-09-2017 |
| 993 | 2 | off | 10:30 22-09-2017 |
| 992 | 1 | on | 09:20 22-09-2017 |
| 991 | 2 | on | 09:20 22-09-2017 |
-- Info table 2 (i2)
+-----+-----+---------+
| id | Cid | task |
+-----+-----+---------+
| 335 | 3 | measure |
| 334 | 2 | reboot |
| 333 | 2 | standby |
| 332 | 1 | fixture |
| 331 | 2 | measure |
-- I want to have it outputted like this (which contains the latest ID's linked to Cid in the result):
+-------------+-----------+----------+------------------+---------+
| Cid & m1 id | location | i1 light | i1 date | i2 task |
+-------------+-----------+----------+------------------+---------+
| 1 | Amsterdam | off | 10:30 22-09-2017 | fixture |
| 2 | Berlin | off | 10:30 22-09-2017 | reboot |
| 3 | Paris | on | 10:30 22-09-2017 | measure |
What I've tried is the following;
SELECT DISTINCT
`m1`.`id`,
`m1`.`location`,
`i1`.`light`,
`i1`,`date`,
`i2`.`task`,
FROM
((`m1`
JOIN `i1` ON ((`i1`.`Cid` = `m1`.`id`)))
JOIN `i2` ON ((`i2`.`Cid` = `m1`.`id`)))
WHERE
`i1`.`id` IN (SELECT
MAX(`i1`.`id`)
FROM
`i1`
GROUP BY `i1`.`Cid`)
ORDER BY `m1`.`id`
Which results only the i1 with no doubles but does give more results of all because there are more i2 rows with that same Cid. I've tried left join as well, but didn't succeed.
Much appreciated!
I know there is probably a better way to do this, but this should work.
SELECT m1.id,
m1.location,
i1_max.light,
i1_max.date,
i2_max.task
FROM m1
JOIN (SELECT id,
Cid,
light,
date
FROM i1
WHERE i1.Cid = m1.id
ORDER BY date DESC
LIMIT 1) AS i1_max
ON m1.id = i1_max.Cid
JOIN (SELECT id,
Cid,
task
FROM i2
WHERE i2.Cid = m1.id
ORDER BY id DESC
LIMIT 1) AS i2_max
ON m1.id = i2_max.Cid
try this one.. it's a sql server format but should just work fine with mysql otherwise format accordingly.
select m.cid, m.location, i1.light,i1.Date,i2.task from
m1 m
inner join
(
select b.cid,b.light,b.date from i1 b where b.id =
(select max(id) from i1 b1 where b1.cid = b.Cid)
) i1 on i1.Cid = m.cid
inner join
(
select c.cid,c.task from i2 c where c.id =
(select max(id) from i2 c1 where c1.cid = c.Cid)
) i2 on i2.Cid = m.cid
select m1.*, i1.light, l1.date, i2.task
from m1 join
(select max(id) id, cid from i1 group by cid) a on m1.cid = a.cid
join
(select max(id) id, cid from i2 group by cid) b on m1.cid = b.cid
join i1 on a.id = i1.id
join i2 on b.id = i2.id
order by m1.cid
;
Update: My answer is using T-SQL. I did not realize that the ask was for MySql database. MySql does not support window functions. Also, support for CTE is only available from MySql 8.0 onwards.
with i1latest (id, cid, light, [date], rown)
as
(
select id, cid, light, [date], row_number() over(partition by cid order by [date] desc) as rown
from i1
), i2latest (id, cid, task, rown)
as
(
select id, cid, task, row_number() over(partition by cid order by id desc) as rown
from i2
)
select m1.cid as cid, m1.location, i1n.light, i1n.[date], i2n.task
from m1
join i1latest i1n
on m1.cid = i1n.cid
join i2latest i2n
on m1.cid = i2n.cid
where i1n.rown = 1
and i2n.rown =1
Result:
cid location light date task
--- ----------- ------ ----------------------- ---------
1 Amsterdam off 2017-03-20 17:23:34.733 fixture
2 Berlin off 2017-03-20 17:23:34.733 reboot
3 Paris on 2017-03-20 17:23:34.733 measure
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.