union all这样写为啥提示“使用 UNION、INTERSECT 或 EXCEPT 运算符合并的所有查询必须在其目标列表中有

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了union all这样写为啥提示“使用 UNION、INTERSECT 或 EXCEPT 运算符合并的所有查询必须在其目标列表中有相关的知识,希望对你有一定的参考价值。

使用 UNION、INTERSECT 或EXCEPT 运算符合并的所有查询必须在其目标列表中有相同数目的表达式
回答的对,但我要的不是这个效果,可能是我问错了,其实用视图可以做的

union 关键字前后的查询返回的列数必须相同。你的这个查询前面返回了13列,后面的查询只返回了3列。缺少的列可以通过显示地指定Null来补充。
例如:
select B.ComplainNo,C.BgDate,A.TrueName,A.Tel,A.Company,A.Department,B.ProductName,B.LyDate,B.SgDate,D.ProductCategory,D.SupplyName,E.PFMoney,C.CloseTime from UserInfo A,Complain B,Complainhead C,Feedbackinformation D,ExecInfo E
WHERE A.UserID=B.UserID and B.ComplainID=C.ComplainID and B.ComplainID=D.ComplainID and B.ComplainID=E.ComplainID
union
select null,null,A.TrueName,null,A.Company,A.Department,null,null,null,null,null,null,null from UserInfo A,Complain B,Complainbody C
where A.UserID=C.DoUserID and B.UserID=C.ApUserID and B.ComplainID=C.ComplainID and C.SortID='3'
参考技术A 你2个select后面的字段名称和数量都不一致当然没半分Union了
请参阅Union方面的知识点
参考技术B UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同!
SQL UNION 语法
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法
SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2
另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
下面的例子中使用的原始表:
Employees_China:
E_ID E_Name
01 Zhang, Hua
02 Wang, Wei
03 Carter, Thomas
04 Yang, Ming

Employees_USA:
E_ID E_Name
01 Adams, John
02 Bush, George
03 Carter, Thomas
04 Gates, Bill
使用 UNION 命令
实例
列出所有在中国和美国的不同的雇员名:
SELECT E_Name FROM Employees_China
UNION
SELECT E_Name FROM Employees_USA
结果
E_Name
Zhang, Hua
Wang, Wei
Carter, Thomas
Yang, Ming
Adams, John
Bush, George
Gates, Bill
注释:这个命令无法列出在中国和美国的所有雇员。在上面的例子中,我们有两个名字相同的雇员,他们当中只有一个人被列出来了。UNION 命令只会选取不同的值。
UNION ALL
UNION ALL 命令和 UNION 命令几乎是等效的,不过 UNION ALL 命令会列出所有的值。
SQL Statement 1
UNION ALL
SQL Statement 2

使用 Union/Union All 插入无法插入所有行

【中文标题】使用 Union/Union All 插入无法插入所有行【英文标题】:Insert using Union/Union All fails to insert all rows 【发布时间】:2021-07-13 20:14:35 【问题描述】:

我正在尝试将 UNION 的结果插入到表中。虽然我无法在此处重现原始查询,但由于它处于受限环境中,它的结构看起来类似于:

WITH temp(X,Y,Z) AS(
SELECT....
)
SELECT X,Y,Z from TEMP --PART A
UNION 
SELECT 'A','B','C' FROM DUAL;--PART B

查询的 A 部分返回大约 1000 条记录,而 B 部分只是一条记录。

当我将整个查询包装在一个过程中,以便将 select 语句的结果插入到表中时,我看到只有 B 部分,一条记录被插入到目标表中。这就是它的样子当我将它包装在过程中时。

CREATE OR REPLACE PROCEDURE PROC_INSERT
AS
BEGIN
INSERT INTO TABLENAME(COLUMN1,COLUMN2....)
 WITH temp(X,Y,Z) AS(
    SELECT....
    )
    SELECT X,Y,Z from TEMP
    UNION 
    SELECT 'A','B','C' FROM DUAL;
COMMIT;
END;

我尝试同时使用 UNION 和 UNION ALL,但不知何故我看不到将结果集的 A 部分插入到表中。

发生这种情况的可能原因是什么?我试图复制相同的,但失败了。

【问题讨论】:

请编辑问题以显示您如何将查询包装在您的过程中。它是单个insert ... with ... select,还是您将其设为游标并逐行插入,或使用批量集合?当您独立运行它时是否有使用文字的过滤器和过程中的变量/参数 - 这可能表明名称或数据类型不匹配?目前真的没有什么可做的。 minimal reproducible example 会很有帮助 - 如果你不能复制它,我们也很难理解或复制它...... 显然从您的描述来看,A 部分不返回行。如果它在 SQL 中有效,但在 PL/SQL 过程中无效,则需要检查您的查询是否仍与 SQL 中的相同。您可以从 10046 跟踪或 v$open_cursor/v$sql 中获取您的真实查询文本。例如,您的过程中可能有与变量同名的别名或列。 @AlexPoole,编辑了您的问题以包括程序的外观。关于最小可重现示例,我无法自己复制它,使用涉及 WITH 和 UNION 子句的类似查询。 对查询没有任何参数或更改?如果单独运行插入会发生什么? (因为过程包装器目前似乎没有添加任何东西)。没有理由 CTE 或 union 会成为您所展示的内容的问题。 CTE 查询仍然可能引用评估不同的东西,可能基于角色 - 或者缺少角色,因为它似乎是定义者的权限程序。我们只能猜测;您需要调试该过程。 @AlexPoole ,独立运行 INSERT 会产生相同的结果 -> B 部分(1 行)被插入。 【参考方案1】:

你可以这样做

DECLARE 
  CURSOR CUR IS SELECT X, Y, Z FROM OG_TABLE UNION SELECT 'A', 'B', 'C' FROM DUAL;
BEGIN 
  
  FOR REC IN CUR 
    LOOP 
    
    INSERT INTO NEWTABLE (COL1, COL2, COL3) VALUES (REC.X, REC.Y, REC.Z);
    
  END LOOP;
  
END;

替代优化代码

DECLARE 
  LIM PLS_INTEGER := 100;

  CURSOR CUR IS SELECT X, Y, Z FROM OG_TABLE UNION SELECT 'A', 'B', 'C' 
  FROM DUAL;
 
  TYPE OG_REC IS RECORD( X OG_TABLE.X%TYPE, Y OG_TABLE.Y%TYPE, Z 
  OG_TABLE%TYPE);

  TYPE OGT IS TABLE OF OG_REC;
  OG_TAB OGT;

BEGIN 
  
  OPEN CUR;
   
  LOOP
    
    FETCH CUR BULK COLLECT INTO OG_TAB LIMIT LIM;
    
        BEGIN
     
             FORALL i IN 1..OG_TAB.COUNT SAVE EXCEPTIONS
             INSERT INTO NEWTABLE (COL1, COL2, COL3) VALUES (OG_TAB(i).X, 
             OG_TAB(i).Y, OG_TAB(i).Z);
    
        EXCEPTION
        WHEN OTHERS THEN
            NULL;
        END;
    
  EXIT WHEN CUR%NOTFOUND;
  END LOOP;
  
  COMMIT;
  CLOSE CUR;
END;

【讨论】:

单个插入比循环和执行 1000 多个单独插入更有效。这可能是 OP 已经在做的事情,但即使没有,我认为这也无助于解决导致联合的第一个分支找不到任何行的问题。 隐式优化 oracle 做了什么?如果不是这样,那么是的,效率不高,最好批量收集并使用FORALL插入数据。 如果Oracle没有隐式优化Cursor For Loop那我真的学错了。 It doesn't。是的,FORALL 会有所改进,但仍然比单个 insert ... select 慢,并且需要更多内存来保存集合。

以上是关于union all这样写为啥提示“使用 UNION、INTERSECT 或 EXCEPT 运算符合并的所有查询必须在其目标列表中有的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Access 中使用 UNION ALL 时出现 ODBC 连接失败错误?

SQL视图提示无法使用Union all求大神帮忙

union和union all用法

union和union all 的写法

UNION 与 UNION ALL 的性能

UNION和UNION ALL