• Union All 使用注意事项和字段顺序不一致导致的异常


    使用注意,先说结果:

    UNION 操作符用于合并两个或多个 SELECT 语句的结果集,这里需要注意的是:

    • UNION 内部的 SELECT 语句必须拥有相同数量的列;
    • 列也必须拥有相似的数据类型(实际非必须);
    • 同时,每条 SELECT 语句中列的顺序必须相同。

    一、表结构数据准备如下:

    1.1 test_union_1

    结构:

    CREATE TABLE `test_union_1` (
      `one` varchar(255) DEFAULT NULL,
      `two` varchar(255) DEFAULT NULL,
      `three` varchar(255) DEFAULT NULL,
      `four` varchar(255) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    

    数据:

    1.2 test_union_2

    结构:

    CREATE TABLE `test_union_2` (
      `four` varchar(255) DEFAULT NULL,
      `three` varchar(255) DEFAULT NULL,
      `two` varchar(255) DEFAULT NULL,
      `one` varchar(255) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    

    数据:

    两表数据一致,字段一致,只是字段顺序不同。
    test_union_1的顺序:one,two,three,four
    test_union_2 的顺序:four,three,two,one

    二、验证

    2.1、验证:UNION 内部的 SELECT 语句必须拥有相同数量的列;

    1562053211947

    2.2、验证:列也必须拥有相似的数据类型(实际非必须);

    这个实际非必须。

    修改表test_union_2 结构如下:String类型改为int类型。

    CREATE TABLE `test_union_2` (
     `four` int(255) DEFAULT NULL,
     `three` int(255) DEFAULT NULL,
     `two` int(255) DEFAULT NULL,
     `one` int(255) DEFAULT NULL
    ) ENGINE = InnoDB CHARSET = latin1;
    

    查询:

    SELECT *
    FROM (
     SELECT one, two, three, four
     FROM test_union_1
     UNION ALL
     SELECT one, two, three, four
     FROM test_union_2
    ) T;
    

    结果:

    所以,实际不是字段类型必须一致,只要可以转换即可。具体转换逻辑暂时不清楚,后续遇到了再搞。

    2.3、验证:每条 SELECT 语句中列的顺序必须相同(亲身踩坑)。

    先来说下,如果顺序不同,会是什么结果?
    答:结果字段的顺序以 union all 前面的表字段顺序为准。
    union all 后面的表的数据会按照顺序依次附在后面。注意:按照字段顺序匹配,而不是按照字段名称匹配。

    测试如下:表顺序对结果的影响

    2.1 test_union_1 UNION ALL test_union_2

    SELECT *
    FROM (
     SELECT *
     FROM test_union_1
     UNION ALL
     SELECT *
     FROM test_union_2
    ) T;
    

    结果:

    可发现:结果字段是test_union_1的字段顺序:one,two,three,four

    2.2 test_union_2 UNION ALL test_union_1

    SELECT *
    FROM (
     SELECT *
     FROM test_union_2
     UNION ALL
     SELECT *
     FROM test_union_1
    ) T;
    

    结果:

    可发现:结果字段是test_union_2的字段顺序:four,three,two,one

    综上:union all结果字段的顺序以 union all 前面的表字段顺序为准。union all 后面的表的数据会按照字段顺序依次附在后面,而不是按照字段名称匹配。

    我们上面以*来表示顺序的不同,其实你写成不同顺序的字段结果一致。我亲测如此,但是不重复贴结果了。

    另外,如果系统中进行了分表,一定要保证各个表的字段顺序一致。特别是修改的时候。否则,如果使用 *汇总查询结果,肯定是会有问题的...亲身踩坑。

  • 相关阅读:
    [CTSC2017]吉夫特(Lucas定理,DP)
    [CTSC2017]游戏(Bayes定理,线段树)
    [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)
    [BZOJ4337][BJOI2015]树的同构(树的最小表示法)
    [BZOJ3786]星系探索(伪ETT)
    [CTSC2017]密钥
    PKUSC2018训练日程(4.18~5.30)
    [NOI2016]优秀的拆分
    [SDOI2008]Sandy的卡片
    [JSOI2007]字符加密
  • 原文地址:https://www.cnblogs.com/buwuliao/p/11121352.html
Copyright © 2020-2023  润新知