UNION ALL两个具有不同列类型的SELECT - 预期行为?

问题描述 投票:4回答:3

当我们对具有不同数据类型的两个表执行UNION时,SQL Standard会产生什么样的预期行为:

create table "tab1" ("c1" varchar(max));
create table "tab2" ("c3" integer);
insert into tab1 values(N'asd'), (N'qweqwe');
insert into tab2 values(123), (345);
select
c_newname as myname
from
(
select "c1" as c_newname from "tab1"
union all
select "c3" from "tab2"
) as T_UNI;

MS SQL Server给出

将varchar值'asd'转换为数据类型int时转换失败。

但是标准中定义了什么?

sql sql-server tsql standards union-all
3个回答
3
投票

如果你想在每个查询中使用union all列需要具有相同的类型.C3必须转换为varchar,因为c1是varchar。尝试以下解决方案

create table "tab1" ("c1" varchar(max));
create table "tab2" ("c3" integer);
insert into tab1 values(N'asd'), (N'qweqwe');
insert into tab2 values(123), (345);
select
c_newname as myname
from
(
select "c1" as c_newname from "tab1"
union all
select cast("c3"  as varchar(max)) from "tab2"
) as T_UNI;

我用"tab3"取代了"tab1" - 我认为这是错字。


4
投票

来自T-SQL UNION页面:

以下是使用UNION组合两个查询的结果集的基本规则:

  • 所有查询中列的数量和顺序必须相同。
  • 数据类型必须兼容。

当一个数据类型是VARCHAR而另一个是INTEGER时,SQL Server将隐式尝试将VARCHAR转换为INTEGER(规则在优先级表中描述)。如果任何行的转换失败,则查询失败。这样可行:

INSERT INTO #tab1 VALUES(N'123'), (N'345');
INSERT INTO #tab2 VALUES(123), (345);
SELECT C1 FROM #tab1 UNION ALL SELECT C2 FROM #tab2

但这不是:

INSERT INTO #tab1 VALUES(N'ABC'), (N'345');
INSERT INTO #tab2 VALUES(123), (345);
SELECT C1 FROM #tab1 UNION ALL SELECT C2 FROM #tab2
-- Conversion failed when converting the varchar value 'ABC' to data type int.

转换规则如下所述:

T-SQL Data Type Precedence


话虽如此,您可以显式地将整数数据转换为varchar,以使查询起作用(结果的数据类型为varchar)。


1
投票

基本规则是 - >在两个表(或)中使用的数据类型应该相同,您应该使用强制转换或转换函数来匹配这两个表中的数据类型。

SQL标准:

1)所有查询中列的数量和顺序必须相同。 2)列数据类型必须兼容:它们不必是完全相同的类型,但它们必须是SQL Server可以隐式转换的类型。

© www.soinside.com 2019 - 2024. All rights reserved.