› 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 · Aug 25, 2020 · 4103 views
    This topic created in 2227 days ago, the information mentioned may be changed or developed.
    https://www.w3school.com.cn/sql/sql_join_left.asp


    想要 结果

    Adams John 24562


    Carter Thomas 77895


    Bush George
    Supplement 1  ·  Aug 25, 2020
    显示 右表中对应 左表里每条记录 oderNo 最大的那条
    13 replies  •  2021-02-20 18:01:31 +08:00
    taogen
        1
    taogen  
       Aug 25, 2020 via Android
    select … from A join B … order by orderNo desc limit 1
    zhenglee
        2
    zhenglee  
       Aug 25, 2020   ❤️ 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  
       Aug 25, 2020 via Android
    @zhenglee group by 和 聚合函数,要使用相同字段
    zhenglee
        4
    zhenglee  
       Aug 25, 2020
    @taogen 没有这么一说,实践出真知。
    taogen
        5
    taogen  
       Aug 25, 2020 via Android
    @zhenglee 不好意思,我记错了。
    CRVV
        6
    CRVV  
       Aug 25, 2020   ❤️ 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  
       Aug 25, 2020
    等等,我是不是理解错了什么
    你要返回右表里 order by NO 最大的那条,那还要 left join 干锤子
    zhangysh1995
        8
    zhangysh1995  
       Aug 25, 2020
    用右表 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
       Aug 25, 2020
    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  
       Aug 25, 2020
    之前遇到过这个问题,牵涉到 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  
       Aug 25, 2020   ❤️ 1
    我之前用子查询好像性能有点问题,找到个只用外连接的办法,楼主试试
    https://stackoverflow.com/a/584442
    JJstyle
        12
    JJstyle  
       Aug 25, 2020
    @zhenglee 有点问题,Bush George 没有订单,被你过滤掉了,但楼主还想在结果中保留他(我可能有点吹毛求疵了)
    JJstyle
        13
    JJstyle  
       Feb 20, 2021   ❤️ 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;
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4219 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 04:03 · PVG 12:03 · LAX 21:03 · JFK 00:03
    ♥ Do have faith in what you're doing.