• MySQL


    有一个表示地区的表,表结构与数据大概如下表。

    ID NAME PARENT_ID
    1 中国  
    2 广东省 1
    3 广州市 2
    4 荔湾区 3
    5 越秀区 3
    6 番禺区 3
    7 小谷围街道 6

    现为了查询方便,需要加一列PARENT_NAME,用以表示上级地区的名称(虽然不符合第三范式,传递依赖,但有时为了业务上的可行性、便利性,可以按实际情况考虑)

    ID NAME PARENT_ID PARENT_NAME
    1 中国    
    2 广东省 1  
    3 广州市 2  
    4 荔湾区 3  
    5 越秀区 3  
    6 番禺区 3  
    7 小谷围街道 6  

    附,表的DDL、DML:

    -- ----------------------------
    -- Table structure for `t_area`
    -- ----------------------------
    
    CREATE TABLE `t_area` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(256) DEFAULT NULL,
      `parent_id` int(11) DEFAULT NULL,
      `parent_name` varchar(256) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of t_area
    -- ----------------------------
    INSERT INTO `t_area` VALUES ('1', '中国', null, null);
    INSERT INTO `t_area` VALUES ('2', '广东省', '1', null);
    INSERT INTO `t_area` VALUES ('3', '广州市', '2', null);
    INSERT INTO `t_area` VALUES ('4', '荔湾区', '3', null);
    INSERT INTO `t_area` VALUES ('5', '越秀区', '3', null);
    INSERT INTO `t_area` VALUES ('6', '番禺区', '3', null);
    INSERT INTO `t_area` VALUES ('7', '小谷围街道', '6', null);
    View Code

    这时,需要根据已有信息,更新PARENT_NAME的数据,就有了如下的SQL:

    /* [Err] 1093 - You can't specify target table 't' for update in FROM clause */
    update t_area t set t.parent_name = (select t2.name from t_area t2 where t.parent_id = t2.id);
    View Code

    报出“1093 - You can't specify target table 't' for update in FROM clause”的异常。意思,意思大约为,你不能指定更新的目标表在FROM子句中(英文不好,即使认识各个单词,串起来就不行了。。。)

    就如文档所述“Currently, you cannot update a table and select from the same table in a subquery.”,见http://dev.mysql.com/doc/refman/5.5/en/update.html。

    不知道MySQL为什么不允许这样操作,猜,可能是担心更新的表与查询的表为同一表会存在嵌套递归?还是担心效率的问题呢?

    如果,将该表在嵌套一层,即“(select * from t_area) st”这样得出一个临时的结果集,即无报错,但,这性能较差,仅仅适合较小的数据量的。(见此讨论帖:http://stackoverflow.com/questions/17742214/you-cant-specify-target-table-name-for-update-in-from-clause)。

    修改后如下:

    --ok
    update t_area t set t.parent_name = (select t2.name from (select * from t_area) t2 where t.parent_id = t2.id);
    View Code

    具体针对这个需求,更简单的方式,貌似也可以:

    update t_area t, t_area t2 set t.parent_name = t2.name where t.parent_id = t2.id;
    View Code
  • 相关阅读:
    L317 电子烟
    L316 波音737Max 危机
    2.19.3月 专业综合错题
    L314 单音节词读音规则(二)-元音字母发音规则
    L313 珊瑚裸鼠灭绝
    L312 难看懂的
    Pycharm写代码中文输入法不跟随
    Windows下Python多版本共存
    Python之批处理字符串(打开文件)
    Python Url请求代码
  • 原文地址:https://www.cnblogs.com/nick-huang/p/4412818.html
Copyright © 2020-2023  润新知