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

SQL 问题请教(mysql)

  •  
  •   CUMTProgrammer · 2020-08-26 17:22:32 +08:00 · 2529 次点击
    这是一个创建于 1560 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 条回复    2020-08-31 18:01:06 +08:00
    youzipi
        1
    youzipi  
       2020-08-26 17:30:34 +08:00   ❤️ 1
    没必要 join 两次吧
    luojianxhlxt
        2
    luojianxhlxt  
       2020-08-26 17:32:33 +08:00   ❤️ 1
    为啥要 join 两次呀
    虽然我都是 a.status =c.id(+)这么写

    这两个来说,第一个好吧
    CUMTProgrammer
        3
    CUMTProgrammer  
    OP
       2020-08-26 17:55:59 +08:00
    @luojianxhlxt
    @youzipi
    如果 join 一次的话,后面的 type 要怎么查询?能否写一下完整的 sql
    两个属性并不是一行数据,type 是一行,status 是一行,是字典表的形式
    CUMTProgrammer
        4
    CUMTProgrammer  
    OP
       2020-08-26 17:57:44 +08:00
    如果是查询一行的话,我也觉得 join 要好,但是这个是 a 的多个属性都要从 b 获取,可以简单的理解 b 只有 id,name 两个字段,a 存着 b 的 id
    bixchen
        5
    bixchen  
       2020-08-26 17:59:07 +08:00   ❤️ 1
    第一种。
    redtea
        6
    redtea  
       2020-08-26 18:18:47 +08:00   ❤️ 1
    把字典表全表查出来,写入缓存,等有数据更新了再更新缓存。
    只要查询 a 表就行了,status 和 type 对应的名称从缓存查。
    如果字典表常年不变的话,作为常量都行。
    justgodlike1993
        7
    justgodlike1993  
       2020-08-26 19:08:45 +08:00   ❤️ 1
    WHERE a.type = c.id?
    lovecy
        8
    lovecy  
       2020-08-26 19:28:52 +08:00   ❤️ 1
    #6 正解,非要 SQL 就第一种了,别纠结了,头发要紧
    realpg
        9
    realpg  
       2020-08-26 19:32:57 +08:00   ❤️ 1
    从语义逻辑上看也是 left join 没啥性能问题
    guanhui07
        10
    guanhui07  
       2020-08-26 19:48:51 +08:00   ❤️ 1
    我也觉得 一次 join
    taogen
        11
    taogen  
       2020-08-26 20:42:19 +08:00 via Android   ❤️ 1
    1. 应该没有。
    2. 习惯第一种写法。
    zhangysh1995
        12
    zhangysh1995  
       2020-08-28 15:40:16 +08:00
    个人觉得第二种更优雅。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
       2020-08-28 17:02:58 +08:00
    @zhangysh1995 兄弟,你的 join 一次写法太想当然了。你可以自己试一次
    jintianfengda
        14
    jintianfengda  
       2020-08-31 18:01:06 +08:00
    字典表放缓存吧,如果非要从 db 查,那就第一种吧,我还是习惯了用 join
    针对 join 一次还是 join 两次的问题,应该是 join 两次,b 是字典表,a 是两个字段需要去查字典,我这么理解没错吧
    还有字典一般都是 Map<K,List<V>>两层结构的吧,这里直接 join 了 id 的话那就应该是单层的了,对我个人来说也怪怪的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1160 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:03 · PVG 07:03 · LAX 15:03 · JFK 18:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.