将单列行集与 Oracle 中的另一个单列行集进行比较 SQL

Compare a single-column row-set with another single-column row set in Oracle SQL

有没有Oracle SQL运算符或函数,比较2个结果集是否完全相同。目前我的想法是在两个方向上都使用 MINUS 运算符,但我正在寻找一个更好、性能更好的解决方案来实现。一个结果集是固定的(见下文),另一个取决于记录。

非常重要:不允许我更改架构和结构。所以 CREATE TABLE CREATE TYPE 等等。我不允许在这里。同样重要的是,必须找到解决方案的地方使用oracle11g版本。

SQL Fiddle 的 shema 是:

CREATE TABLE DETAILS (ID INT, MAIN_ID INT, VALUE INT);

INSERT INTO DETAILS VALUES (1,1,1);
INSERT INTO DETAILS VALUES (2,1,2);
INSERT INTO DETAILS VALUES (3,1,3);
INSERT INTO DETAILS VALUES (4,1,4);
INSERT INTO DETAILS VALUES (5,2,1);
INSERT INTO DETAILS VALUES (6,2,2);
INSERT INTO DETAILS VALUES (7,3,1);
INSERT INTO DETAILS VALUES (7,3,2);

现在这是我的 SQL 查询(选择 MAIN_IDs 个,其“VALUE”与给定列表完全相同):

SELECT DISTINCT D.MAIN_ID FROM DETAILS D WHERE NOT EXISTS
  (SELECT VALUE FROM DETAILS WHERE MAIN_ID=D.MAIN_ID
  MINUS
  SELECT * FROM TABLE(SYS.ODCINUMBERLIST(1, 2)))
AND NOT EXISTS
  (SELECT * FROM TABLE(SYS.ODCINUMBERLIST(1, 2))
  MINUS
  SELECT VALUE FROM DETAILS WHERE MAIN_ID=D.MAIN_ID)

SQL Fiddle link: http://sqlfiddle.com/#!4/25dde/7/0

如果您使用集合(而不是 VARRAY),那么您可以将值聚合到一个集合中并直接比较两个集合:

CREATE TYPE int_list AS TABLE OF INT;

然后:

SELECT main_id
FROM   details
GROUP BY main_id
HAVING CAST( COLLECT( value ) AS int_list ) = int_list( 1, 2 );

输出:

| MAIN_ID |
| ------: |
|       2 |
|       3 |

db<>fiddle here

更新

根据您在评论中展开的fiddle,您可以使用:

SELECT B.ID
FROM  BUSINESS_DATA B
      INNER JOIN BUSINESS_NAME N
      ON ( B.NAME_ID=N.ID )
WHERE N.NAME='B1'
AND   EXISTS (
        SELECT business_id
        FROM   ORDERS O
               LEFT OUTER JOIN TABLE(
                 SYS.ODCIDATELIST( DATE '2021-01-03', DATE '2020-04-07', DATE '2020-05-07' )
               ) d
               ON ( o.orderdate = d.COLUMN_VALUE )
        WHERE  O.BUSINESS_ID=B.ID
        GROUP BY business_id
        HAVING COUNT( CASE WHEN d.COLUMN_VALUE IS NULL THEN 1 END ) = 0
        AND    COUNT( DISTINCT o.orderdate )
               = ( SELECT COUNT(DISTINCT COLUMN_VALUE) FROM TABLE( SYS.ODCIDATELIST( DATE '2021-01-03', DATE '2020-04-07', DATE '2020-05-07' ) ) )
      )

(注意:不要隐式地从字符串创建日期;如果用户更改他们的 NLS_DATE_FORMAT 会话,这将导致查询失败,并且查询文本没有任何更改参数。而是将 TO_DATE 与适当的格式模型或 DATE 文字一起使用。)

db<>fiddle here