MySql从3个表中创建具有最新ID的视图

时间:2017-03-20 22:08:24

标签: mysql sql

我尝试了几次不同的方法,但没有像它应该的那样工作:

- 主表(m1)

+-----+-----------+
| Cid | location  |
+-----+-----------+
|  1  | Amsterdam |
|  2  | Berlin    |
|  3  | Paris     |

- 信息表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 |

- 资料表2(i2)

+-----+-----+---------+
| id  | Cid |  task   |
+-----+-----+---------+
| 335 |   3 | measure |
| 334 |   2 | reboot  |
| 333 |   2 | standby |
| 332 |   1 | fixture |
| 331 |   2 | measure |

- 我想让它像这样输出(其中包含与结果中的Cid相关联的最新ID):

+-------------+-----------+----------+------------------+---------+
| 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 |

我尝试的是以下内容;

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`

这导致只有i1没有双打,但确实提供了更多的结果,因为有更多的i2行具有相同的Cid。我也尝试过离开加入,但没有成功。

非常感谢!

4 个答案:

答案 0 :(得分:0)

我知道可能有更好的方法来做到这一点,但这应该有用。

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

答案 1 :(得分:0)

尝试这个..它是一个sql服务器格式,但应该可以正常使用mysql,否则格式化。

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

答案 2 :(得分:0)

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
;

答案 3 :(得分:0)

更新:我的回答是使用T-SQL。我没有意识到问题是针对MySql数据库的。 MySql不支持窗口函数。此外,仅从MySql 8.0开始提供对CTE的支持。

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

结果:

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