› 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
CUMTProgrammer
V2EX  ›  MySQL

SQL 问题请教(mysql)

  •  
  •   CUMTProgrammer · Aug 26, 2020 · 3618 views
    This topic created in 2225 days ago, the information mentioned may be changed or developed.

    select a.id, c.name as status ,d.name as type 
    from a 
    left join b c on a.status =c.id
    left join b d on a.type =d.id
    

    select a.id,
    (selct name from b where a.status = b.id) as status,
    (selct name from b where a.type = b.id) as type
    from a
    

    a 表与 b 表关联,b 作为字典表,存着名称等信息,a 只有 id 。

    不讨论这个表结构改变等等(以及用了很久,数据很多,而且不是我能决定的),仅从 SQL 角度

    1.两种写法我都觉得很丑陋,有没有更好的

    2.如果没有的话,哪一种稍微好一点

    14 replies  •  2020-08-31 18:01:06 +08:00
    youzipi
        1
    youzipi  
       Aug 26, 2020   ❤️ 1
    没必要 join 两次吧
    luojianxhlxt
        2
    luojianxhlxt  
       Aug 26, 2020   ❤️ 1
    为啥要 join 两次呀
    虽然我都是 a.status =c.id(+)这么写

    这两个来说,第一个好吧
    CUMTProgrammer
        3
    CUMTProgrammer  
    OP
       Aug 26, 2020
    @luojianxhlxt
    @youzipi
    如果 join 一次的话,后面的 type 要怎么查询?能否写一下完整的 sql
    两个属性并不是一行数据,type 是一行,status 是一行,是字典表的形式
    CUMTProgrammer
        4
    CUMTProgrammer  
    OP
       Aug 26, 2020
    如果是查询一行的话,我也觉得 join 要好,但是这个是 a 的多个属性都要从 b 获取,可以简单的理解 b 只有 id,name 两个字段,a 存着 b 的 id
    bixchen
        5
    bixchen  
       Aug 26, 2020   ❤️ 1
    第一种。
    redtea
        6
    redtea  
       Aug 26, 2020   ❤️ 1
    把字典表全表查出来,写入缓存,等有数据更新了再更新缓存。
    只要查询 a 表就行了,status 和 type 对应的名称从缓存查。
    如果字典表常年不变的话,作为常量都行。
    justgodlike1993
        7
    justgodlike1993  
       Aug 26, 2020   ❤️ 1
    WHERE a.type = c.id?
    lovecy
        8
    lovecy  
       Aug 26, 2020   ❤️ 1
    #6 正解,非要 SQL 就第一种了,别纠结了,头发要紧
    realpg
        9
    realpg  
       Aug 26, 2020   ❤️ 1
    从语义逻辑上看也是 left join 没啥性能问题
    guanhui07
        10
    guanhui07  
       Aug 26, 2020   ❤️ 1
    我也觉得 一次 join
    taogen
        11
    taogen  
       Aug 26, 2020 via Android   ❤️ 1
    1. 应该没有。
    2. 习惯第一种写法。
    zhangysh1995
        12
    zhangysh1995  
       Aug 28, 2020
    个人觉得第二种更优雅。a.type, a.id, b.id 如果有索引,支持第二种,速度应该会更快。

    第一种的话 left join 一次就好, `xxx on a.status = b.id and a.type = b.id`, 需要加索引 (status, type), 注意 predicate 顺序
    CUMTProgrammer
        13
    CUMTProgrammer  
    OP
       Aug 28, 2020
    @zhangysh1995 兄弟,你的 join 一次写法太想当然了。你可以自己试一次
    jintianfengda
        14
    jintianfengda  
       Aug 31, 2020
    字典表放缓存吧,如果非要从 db 查,那就第一种吧,我还是习惯了用 join
    针对 join 一次还是 join 两次的问题,应该是 join 两次,b 是字典表,a 是两个字段需要去查字典,我这么理解没错吧
    还有字典一般都是 Map<K,List<V>>两层结构的吧,这里直接 join 了 id 的话那就应该是单层的了,对我个人来说也怪怪的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   3206 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 04:31 · PVG 12:31 · LAX 21:31 · JFK 00:31
    ♥ Do have faith in what you're doing.