简体   繁体   中英

MySql create view from 3 tables with latest id's

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

Rextester demo

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM