INTERSECT 子句

计算两个或更多 SELECT 查询结果的交集。INTERSECT 返回 INTERSECT 操作数左右两侧查询的唯一值。

语法

select‑stmt
    INTERSECT query[...]
    [ order-by-clause  [ offset-clause ]]
    [ limit-clause ]

注意

  • INTERSECT 子句返回 SELECT 查询结果的交集。INTERSECT 查询对两个或更多 SELECT 查询的结果执行操作。INTERSECT 仅返回所有指定查询所得到的行。

  • 不能将 ALL 关键字与 INTERSECT 查询一起使用。

  • 每个 SELECT 查询的结果必须是联集兼容的;必须返回相同数目的列,而且相应的列必须含有兼容的数据类型。例如,不能对 INTERSECT 类型的列和 VARCHAR 类型的列使用 EXCEPT 子句。如果 SELECT 查询不满足这些条件,Vertica 将返回错误。

  • 使用 ORDER BY 子句为 INTERSECT 操作结果进行排序。在 ORDER BY 列表中,指定最左侧 SELECT 语句的列,或指定所按照排序列的所在位置。

  • 您可以在 FROM、WHERE 和 HAVING 子句中使用 INTERSECT。

  • 由于最右侧的查询指定 Vertica 对 INTERSECT 操作的结果执行操作,因此 INTERSECT 查询的 ORDER BY、LIMIT 或者 OFFSET 子句不需要加括号。包含在 SELECT 查询中且之前出现在 INTERSECT 查询中的任何 ORDER BY、LIMIT 或 OFFSET 子句都必须括在圆括号中。

  • 排序列名称来自于第一个 select。

  • Vertica 支持 INTERSECT 非相关子查询谓词。例如:

    => SELECT * FROM T1
       WHERE T1.x IN
          (SELECT MAX(c1) FROM T2
           INTERSECT
              SELECT MAX(cc1) FROM T3
           INTERSECT
              SELECT MAX(d1) FROM T4);
    

示例

假设有下面三个表:

Company_A

id       emp_lname     dept          sales
------+------------+----------------+-------
1234  | Stephen    | auto parts     | 1000
5678  | Alice      | auto parts     | 2500
9012  | Katherine  | floral         |  500
3214  | Smithson   | sporting goods | 1500

Company_B

id       emp_lname     dept        sales
------+------------+-------------+-------
4321  | Marvin     | home goods  |   250
9012  | Katherine  | home goods  |   500
8765  | Bob        | electronics | 20000
3214  | Smithson   | home goods  |  1500

Company_C

  id  | emp_lname |      dept      | sales
------+-----------+----------------+-------
 3214 | Smithson  | sporting goods |  1500
 5432 | Madison   | sporting goods |   400
 7865 | Cleveland | outdoor        |  1500
 1234 | Stephen   | floral         |  1000

以下查询返回 Company_A 和 Company_B 中都包含的 ID 号以及员工姓氏:

=> SELECT id, emp_lname FROM Company_A
   INTERSECT
   SELECT id, emp_lname FROM Company_B;
 id   | emp_lname
------+-----------
 3214 | Smithson
 9012 | Katherine
(2 rows)

接下来的查询返回相同的两个员工,销售额降序排列:

=> SELECT id, emp_lname, sales FROM Company_A
   INTERSECT
   SELECT id, emp_lname, sales FROM Company_B
   ORDER BY sales DESC;
  id  | emp_lname | sales
------+-----------+-------
 3214 | Smithson  |  1500
 9012 | Katherine |   500
(2 rows)

接下来的查询返回同时为两个公司工作而在 Company_B 公司中的销售额超过 1000 的员工姓名:

=> SELECT id, emp_lname, sales FROM Company_A
   INTERSECT
   (SELECT id, emp_lname, sales FROM company_B WHERE sales > 1000)
   ORDER BY sales DESC;
  id  | emp_lname | sales
------+-----------+-------
 3214 | Smithson  |  1500
(1 row)

接下来的查询返回同时为三个公司工作的员工 ID 号以及员工姓氏。

=> SELECT id, emp_lname FROM Company_A
    INTERSECT
   SELECT id, emp_lname FROM Company_B
   INTERSECT
   SELECT id, emp_lname FROM Company_C;
  id  | emp_lname
------+-----------
 3214 | Smithson
(1 row)

接下来的查询返回的是不匹配的数据类型结果;这两个查询不是联集兼容的:

=> SELECT id, emp_lname FROM Company_A
    INTERSECT
   SELECT emp_lname, id FROM Company_B;
ERROR 3429:  For 'INTERSECT', types int and varchar are inconsistent
DETAIL:  Columns: id and emp_lname

使用 VMart 示例数据库,接下来的查询返回有关通过在线销售渠道购买商品且购买金额超过 400 美元和 500 美金的所有康涅狄格州客户的信息:

=> SELECT customer_key, customer_name from public.customer_dimension
       WHERE customer_key IN (SELECT customer_key
         FROM online_sales.online_sales_fact
         WHERE sales_dollar_amount > 400
         INTERSECT
         SELECT customer_key FROM online_sales.online_sales_fact
         WHERE sales_dollar_amount > 500)
      AND customer_state = 'CT' ORDER BY customer_key;
 customer_key |     customer_name
--------------+------------------------
           39 | Sarah S. Winkler
           44 | Meghan H. Overstreet
           70 | Jack X. Cleveland
          103 | Alexandra I. Vu
          110 | Matt . Farmer
          173 | Mary R. Reyes
          188 | Steve G. Williams
          233 | Theodore V. McNulty
          250 | Marcus E. Williams
          294 | Samantha V. Young
          313 | Meghan P. Pavlov
          375 | Sally N. Vu
          384 | Emily R. Smith
          387 | Emily L. Garcia
...

上一个查询和下一个查询是等效的,并且返回相同的结果:

=> SELECT customer_key,customer_name FROM public.customer_dimension
       WHERE customer_key IN (SELECT customer_key
      FROM online_sales.online_sales_fact
         WHERE sales_dollar_amount > 400
         AND sales_dollar_amount < 500)
   AND customer_state = 'CT' ORDER BY customer_key;

另请参阅