UNION ALL 两个具有不同列类型的 SELECT - 预期行为?
UNION ALL two SELECTs with different column types - expected behaviour?
当我们对具有不同数据类型的两个表执行 UNION
时,由于 SQL 标准,预期的行为是什么:
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
给出
Conversion failed when converting the varchar value 'asd' to data type
int.
但是标准中定义了什么?
如果要在每个查询中使用 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;
我用 "tab1"
替换了 "tab3"
- 我认为这是错字。
来自 T-SQL UNION 页:
The following are basic rules for combining the result sets of two
queries by using UNION:
- The number and the order of the columns must be the same in all queries.
- The data types must be compatible.
当一种数据类型是 VARCHAR
而另一种是 INTEGER
时,SQL 服务器将隐式尝试将 VARCHAR
转换为 INTEGER
(规则描述在优先级 table)。如果任何行的转换失败,则查询失败。所以这有效:
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.
这里描述了转换规则:
话虽如此,您可以显式将整数数据转换为 varchar 以使查询工作(结果的数据类型为 varchar)。
基本规则是-->
要么使用的数据类型在两个table中相同(或者)你应该使用转换或转换函数来匹配这两个[=23=中的数据类型]s.
SQL 标准:
1)所有查询中列的数量和顺序必须相同。
2) 列数据类型必须兼容:它们不需要完全相同的类型,但它们必须是 SQL 服务器可以隐式转换的类型。
当我们对具有不同数据类型的两个表执行 UNION
时,由于 SQL 标准,预期的行为是什么:
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
给出
Conversion failed when converting the varchar value 'asd' to data type int.
但是标准中定义了什么?
如果要在每个查询中使用 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;
我用 "tab1"
替换了 "tab3"
- 我认为这是错字。
来自 T-SQL UNION 页:
The following are basic rules for combining the result sets of two queries by using UNION:
- The number and the order of the columns must be the same in all queries.
- The data types must be compatible.
当一种数据类型是 VARCHAR
而另一种是 INTEGER
时,SQL 服务器将隐式尝试将 VARCHAR
转换为 INTEGER
(规则描述在优先级 table)。如果任何行的转换失败,则查询失败。所以这有效:
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.
这里描述了转换规则:
话虽如此,您可以显式将整数数据转换为 varchar 以使查询工作(结果的数据类型为 varchar)。
基本规则是--> 要么使用的数据类型在两个table中相同(或者)你应该使用转换或转换函数来匹配这两个[=23=中的数据类型]s.
SQL 标准:
1)所有查询中列的数量和顺序必须相同。
2) 列数据类型必须兼容:它们不需要完全相同的类型,但它们必须是 SQL 服务器可以隐式转换的类型。