testbook

集合运算:UNION/INTERCEPT/EXCEPT

Inceptor提供三种方法来对SELECT语句结果进行集合运算:并集(UNION)、交集(INTERSECT)和减去(EXCEPT)。而每个集合运算都有两种选择, 带有ALL和不带有ALL。所以我们一共有以下六个集合运算:

  • UNION/UNION ALL
  • INTERSECT/INTERSECT ALL
  • EXCEPT/EXCEPT ALL
  • 集合运算的语法相似:
    语法

    select_expression_1 (UNION|INTERSECT|EXCEPT) select_expression_2
    select_expression_1 (UNION ALL|INTERSECT ALL|EXCEPT ALL) select_expression_2
    
    可以将多个SELECT语句的结果合成单个结果。如果说JOIN是将表左右连接,那么集合运算是以一定条件将表首尾相接,所以 其中每一个SELECT语句返回的列数必须相同,列值类型必须对应,对应列列名也必须相同。否则Inceptor会抛出一个schema error。当SELECT语句结果列名不同时,要使用列化名。
    一次查询中我们也可以进行多次集合运算,比如:
    select_expression_1 UNION select_expression_2 UNION select_expreession_3 INTERSECT select_expression_4 ...
    

    下面,我们将用test_a和test_b两张表来演示如何进行集合运算:
    [$host] transwarp> DESCRIBE test_a;
    a_int                   int                     None
    a_double                double                  None
    a_string                string                  None
    
    [$host] transwarp> SELECT * FROM test_a;
    1       1.01    a
    1       1.02    b
    1       1.02    b
    2       2.02    c
    2       2.04    c
    3       3.03    d
    
    [$host] transwarp> DESCRIBE test_b;
    b_int                   int                     None
    b_string1               string                  None
    b_double                double                  None
    b_string2               string                  None
    
    [$host] transwarp> SELECT * FROM test_b;
    1       b       1.02    f
    1       c       1.04    g
    

    UNION 和 UNION ALL

    UNION和UNION ALL形成查询结果的并集。
    UNION

    注意: 在Inceptor中,UNION和UNION ALL的语法和用法完全相同,尤其是它们都不去重
    语法

    select_statement_1 UNION select_statement_2
    select_statement_1 UNION ALL select_statement_2
    

    如果我们要对UNION ALL的结果进行进一步的处理,我们可以像下面这样将整个UNION子句内嵌进一个FROM子句:

    SELECT *
    FROM (
      select_statement
      UNION ALL
      select_statement
    ) unionResult
    
    举例
    取test_a和test_b两表的并集,注意表test_a中有三列而表test_b中有四列,所以去并集时必须有所筛选:
    [$host] transwarp> SELECT a_int union_int, a_double union_double, a_string union_string FROM test_a UNION SELECT b_int union_int, b_double union_double, b_string1 union_string FROM test_b;
    1       1.01    a
    1       1.02    b
    1       1.02    b
    2       2.02    c
    2       2.04    c
    3       3.03    d
    1       1.02    b
    1       1.04    c
    

    INTERSECT 和 INTERSECT ALL

    INTERSECT和INTERSECT ALL返回两个查询结果的交集。
    intersect
    INTERSECT对返回的结果去重,而INTERSECT ALL不去重。它们的语法相同:
    语法
    select_expression_1 INTERSECT select_expression_2
    select_expression_1 INTERSECT ALL select_expression_2
    
    举例
    INTERSECT 去重:
    [$host] transwarp> SELECT a_int ii, a_double id, a_string is FROM test_a INTERSECT SELECT b_int ii, b_double id, b_string1 is FROM test_b;
    1       1.02    b
    
    INTERSECT ALL不去重:
    [$host] transwarp> SELECT a_int ii, a_double id, a_string is FROM test_a INTERSECT ALL SELECT b_int ii, b_double id, b_string1 is FROM test_b;
    1       1.02    b
    1       1.02    b
    

    EXCEPT 和 EXCEPT ALL

    EXCEPT和EXCEPT ALL做集合减法。A EXCEPT B 将A中所有和B重合的记录除去,然后返回去重后的A中剩下的记录A EXCEPT B 将A中所有和B重合的记录除去,然后不去重的A中剩下的记录。 EXCEPT和EXCEPT ALL的语法相同:
    select_statement_1 EXCEPT select_statement_2
    select_statement_1 EXCEPT ALL select_statement_2
    


    EXCEPT

    举例
    EXCEPT

    [$host] transwarp> SELECT a_int ei FROM test_a EXCEPT SELECT b_int ei FROM test_b;
    2
    3
    
    EXCEPT ALL
    [$host] transwarp> SELECT a_int ei FROM test_a EXCEPT ALL SELECT b_int ei FROM test_b;
    2
    2
    3