V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
rqxiao
V2EX  ›  MySQL

请教 left join 右表后,只返回 在 leftjoin 的结果里,返回右表中 OrderNo 最大的那一条

  •  
  •   rqxiao · 2020-08-25 10:33:12 +08:00 · 2696 次点击
    这是一个创建于 1311 天前的主题,其中的信息可能已经有所发展或是发生改变。
    https://www.w3school.com.cn/sql/sql_join_left.asp


    想要 结果

    Adams John 24562


    Carter Thomas 77895


    Bush George
    第 1 条附言  ·  2020-08-25 13:58:31 +08:00
    显示 右表中对应 左表里每条记录 oderNo 最大的那条
    13 条回复    2021-02-20 18:01:31 +08:00
    taogen
        1
    taogen  
       2020-08-25 10:44:45 +08:00 via Android
    select … from A join B … order by orderNo desc limit 1
    zhenglee
        2
    zhenglee  
       2020-08-25 10:47:07 +08:00   ❤️ 1
    SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
    FROM Persons
    LEFT JOIN Orders
    ON Persons.Id_P=Orders.Id_P
    where Orders.OrderNo in
    (select max(OrderNo) from Orders group by ID_P)
    ORDER BY Persons.LastName
    taogen
        3
    taogen  
       2020-08-25 10:58:23 +08:00 via Android
    @zhenglee group by 和 聚合函数,要使用相同字段
    zhenglee
        4
    zhenglee  
       2020-08-25 11:19:00 +08:00
    @taogen 没有这么一说,实践出真知。
    taogen
        5
    taogen  
       2020-08-25 12:25:38 +08:00 via Android
    @zhenglee 不好意思,我记错了。
    CRVV
        6
    CRVV  
       2020-08-25 13:14:14 +08:00   ❤️ 2
    只取最大的一条可以不用 JOIN

    SELECT Persons.LastName, Persons.FirstName,
    (SELECT max(OrderNo) FROM Orders WHERE Orders.Id_P = Persons.Id_P) AS OrderNo
    FROM Persons;

    如果要取最大的两条,就得用 2 楼的方法

    也可以用 window function,MySQL 8 支持了
    weizhen199
        7
    weizhen199  
       2020-08-25 13:32:28 +08:00
    等等,我是不是理解错了什么
    你要返回右表里 order by NO 最大的那条,那还要 left join 干锤子
    zhangysh1995
        8
    zhangysh1995  
       2020-08-25 13:49:00 +08:00
    用右表 EXISTS 测试相等的值在左表是否存在,两张表 Id_P 加索引

    SELECT max(OrderNo)
    FROM (
    SELECT Orders.Id, OrderNo
    FROM Orders
    WHERE EXISTS (
    SELECT *
    FROM Persons
    WHERE Orders.ID_P = Persons.Id_P)
    ) t;

    MySQL 中 EXISTS 部分 SELECT * 不会实际取数据,对速度没影响。
    rqxiao
        9
    rqxiao  
    OP
       2020-08-25 14:02:13 +08:00
    SELECT
    a.*,
    b.*
    FROM
    lefta a
    LEFT JOIN ( SELECT max( id ), a_id FROM leftb GROUP BY a_id ) b ON a.id = b.a_id
    差不多这样子也行了
    alex321
        10
    alex321  
       2020-08-25 14:19:53 +08:00
    之前遇到过这个问题,牵涉到 4 张表的数据,其中 1 张表需要按照题主的情况读取。当时一时没想到啥办法,就使用了分解成两步的方式处理。
    刚才使用 #6 的方式,重新尝试了下,证实是可行的,但请注意直接查询时的性能损耗。我这里实际测试的结果,4 张表总和差不多 1000 条数据,分解方式的页面总执行时间是 0.0880s,新方式的页面总执行时间是 0.1110s 。多次执行时间相对稳定。
    基于环境:Windows 7 64Bit + IIS 7.5 + PHP 5.6.40 32Bit ( FastCGI ) + MariaDB 5.5.66 ,各表均是 MyISAM 、utf8_general_ci 和自增主键,并设置了索引,没有使用缓存。
    xhq
        11
    xhq  
       2020-08-25 14:33:19 +08:00   ❤️ 1
    我之前用子查询好像性能有点问题,找到个只用外连接的办法,楼主试试
    https://stackoverflow.com/a/584442
    JJstyle
        12
    JJstyle  
       2020-08-25 17:45:21 +08:00
    @zhenglee 有点问题,Bush George 没有订单,被你过滤掉了,但楼主还想在结果中保留他(我可能有点吹毛求疵了)
    JJstyle
        13
    JJstyle  
       2021-02-20 18:01:31 +08:00   ❤️ 1
    把 @zhangysh1995 的 sql 整理了一下,感觉这个比较靠谱

    SELECT
    a.LastName ,
    a.FirstName ,
    b.OrderNo
    FROM
    Persons a
    LEFT JOIN(
    SELECT
    MAX(OrderNo) OrderNo ,
    Id_P
    FROM
    Orders
    GROUP BY
    ID_P
    ) b ON a.Id_P = b.Id_P;
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1324 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:32 · PVG 07:32 · LAX 16:32 · JFK 19:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.