Halo Tech

Halo嵌套表的MULTISET多集运算功能炫酷登场!

一、简介

    为了让咱们的羲和通用数据库系统软件和Oracle数据库更“合拍”,我们重磅推出了Oracle数据库MULTISET多集运算功能!主要亮点有:

    MULTISET UNION(并集): 默认把两个嵌套表的所有元素都招呼进来!

    MULTISET INTERSECT(交集):只留下两个嵌套表都有的“共同好友”!

    MULTISET EXCEPT(差集):找出第一个嵌套表有,但第二个没有的“独家宝贝”!

这些功能都贴心支持ALL或DISTINCT关键字,默认是ALL模式走起。

    ALL:结果里元素可以“刷存在感”(允许重复)。

    DISTINCT:结果里元素都是“独一无二”(去重)。

    特别提示:MULTISET EXCEPT DISTINCT可厉害了,它会直接把左集里所有在右集出现过的元素统统“踢飞”,不管出现多少次!

二、主要功能秀起来

2.1 SQL中使用单个MULTISET多集运算

-- 定义数值型嵌套表类型

CREATE OR REPLACE TYPE numset_t AS TABLE OF NUMBER;

-- 不去重模式 (ALL)

SELECT numset_t(1,1,2,3) MULTISET UNION numset_t(1,4) FROM DUAL;SELECT numset_t(1,1,2,2,3) MULTISET INTERSECT numset_t(1,1,2,4) FROM DUAL;SELECT numset_t(1,1,2,2,2,3) MULTISET EXCEPT numset_t(1,1,2,4) FROM DUAL;

-- 去重模式 (DISTINCT)

SELECT numset_t(1,1,2,3) MULTISET UNION DISTINCT numset_t(1,4) FROM DUAL;SELECT numset_t(1,1,2,2,3) MULTISET INTERSECT DISTINCT numset_t(1,1,2,4) FROM DUAL;SELECT numset_t(1,1,2,2,2,3) MULTISET EXCEPT DISTINCT numset_t(1,1,2,4) FROM DUAL;

执行结果如图:

Image
Image

2.2 过程语言(PL/SQL)中使用MULTISET多集运算

DECLARE   nt1 numset_t := numset_t(1,1,2,2,2,3);  nt2 numset_t := numset_t(1,1,2,4);  m1_a  numset_t := numset_t();  m1_d  numset_t := numset_t();  m2_a  numset_t := numset_t();  m2_d  numset_t := numset_t();  m3_a  numset_t := numset_t();  m3_d  numset_t := numset_t();BEGIN   m1_a := nt1 MULTISET UNION nt2;  m1_d := nt1 MULTISET UNION DISTINCT nt2;  m2_a := nt1 MULTISET INTERSECT nt2;  m2_d := nt1 MULTISET INTERSECT DISTINCT nt2;  m3_a := nt1 MULTISET EXCEPT nt2;  m3_d := nt1 MULTISET EXCEPT DISTINCT nt2;  DBMS_OUTPUT.PUT_LINE('*************并集,不去重****************');  FOR i IN 1..m1_a.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m1_a(i));  END LOOP;  DBMS_OUTPUT.PUT_LINE('*************并集,去重******************');  FOR i IN 1..m1_d.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m1_d(i));  END LOOP;  DBMS_OUTPUT.PUT_LINE('*************交集,不去重****************');  FOR i IN 1..m2_a.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m2_a(i));  END LOOP;  DBMS_OUTPUT.PUT_LINE('*************交集,去重******************');  FOR i IN 1..m2_d.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m2_d(i));  END LOOP;  DBMS_OUTPUT.PUT_LINE('*************差集,不去重****************');  FOR i IN 1..m3_a.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m3_a(i));  END LOOP;  DBMS_OUTPUT.PUT_LINE('*************差集,去重******************');  FOR i IN 1..m3_d.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m3_d(i));  END LOOP;END;/

执行结果如图:

Image

2.3 SQL中使用多个MULTISET多集运算(玩组合技!)

SELECT numset_t(1,1,2,2,2,3) MULTISET INTERSECT numset_t(1,1,2,4) MULTISET UNION numset_t(1,1,2,4) MULTISET EXCEPT numset_t(1,1,2,2,2,3) FROM DUAL;

执行结果如图:

Image

2.4 过程语言中使用多个MULTISET多集运算(更复杂的组合技!)

DECLARE   nt1 numset_t := numset_t(1,1,2,2,2,3);  nt2 numset_t := numset_t(1,1,2,4);  m1  numset_t := numset_t();  m2  numset_t := numset_t();  m3  numset_t := numset_t();  m4  numset_t := numset_t();  m5  numset_t := numset_t();BEGIN   m1 := nt1 MULTISET EXCEPT nt2 MULTISET UNION nt2 MULTISET EXCEPT nt2;  m2 := nt1 MULTISET EXCEPT nt2 MULTISET UNION nt2;  m3 := nt1 MULTISET EXCEPT nt2 MULTISET UNION nt2 MULTISET INTERSECT DISTINCT nt2;  m4 := nt1 MULTISET INTERSECT nt2 MULTISET INTERSECT nt2 MULTISET INTERSECT DISTINCT nt2;  m5 := nt1 MULTISET INTERSECT nt2 MULTISET UNION nt2 MULTISET EXCEPT nt1;  DBMS_OUTPUT.PUT_LINE('*************m1****************');  FOR i IN 1..m1.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m1(i));  END LOOP;  DBMS_OUTPUT.PUT_LINE('*************m2****************');  FOR i IN 1..m2.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m2(i));  END LOOP;  DBMS_OUTPUT.PUT_LINE('*************m3****************');  FOR i IN 1..m3.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m3(i));  END LOOP;  DBMS_OUTPUT.PUT_LINE('*************m4****************');  FOR i IN 1..m4.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m4(i));  END LOOP;  DBMS_OUTPUT.PUT_LINE('*************m5****************');  FOR i IN 1..m5.COUNT LOOP      DBMS_OUTPUT.PUT_LINE('第'||i||'个数 :'||m5(i));  END LOOP;END;/

1) 在Halo中执行上述语句结果如图:

Image

2) 在Oracle 19.3.0.0版本中执行相同语句结果如图:

Image

三、总结

    2.1-2.3中的语句分别在Halo与Oracle中执行,两者结果一致因此仅附上Halo执行结果。

   2.4中的语句分别在Halo与Oracle中执行,由结果图可知m1,m2,m4,m5两者相同,但是m3不同。由m2的结果可知,m3中nt1 MULTISET EXCEPT nt2 MULTISET UNION nt2运算结果为{2,2,3,1,1,2,4},与nt2即{1,1,2,4}进行MULTISET INTERSECT DISTINCT运算,结果应为{1,2,4}。但是,Oracle输出为{2,2,3,1,2,4},与多集运算实际情况相悖,所以这里Halo没有与Oracle保持一致。

    通过2.4中m4和m5结果可知,Oracle中当第一个多集运算为MULTISET INTERSECT,或仅有多个MULTISET INTERSECT运算时,与多集运算实际情况相符,这里Halo与Oracle保持一致。