【问题标题】:UNION ALL two SELECTs with different column types - expected behaviour?UNION ALL 两个具有不同列类型的 SELECT - 预期的行为?
【发布时间】:2019-03-13 02:19:51
【问题描述】:

当我们对具有不同数据类型的两个表执行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给了

将 varchar 值“asd”转换为数据类型时转换失败 诠释。

但是标准中定义了什么?

【问题讨论】:

  • 不确定“tab3”的来源,但您不能合并两种不同的数据类型。这就是 SQL Server 告诉你的。
  • @ChristianBarron 谢谢,tab3 是 tab1,抱歉。我明白 SQL Server 告诉我什么,我想知道 SQL 标准在这个问题上是怎么说的。

标签: sql sql-server tsql standards union-all


【解决方案1】:

来自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)。

【讨论】:

  • cool,谢谢提到数据类型优先级,我不知道这个。
【解决方案2】:

如果您想在每个查询中使用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" - 我认为这是错字。

【讨论】:

  • 感谢您的努力 - 我知道以这种方式修复查询的可能性,但我仍然想知道 SQL 标准的期望。
  • @alex 正如我上面所说的。每个查询中的列类型都应匹配。如果第一列是 int,则每个查询都应返回 int 值。
【解决方案3】:

基本规则是--> 两个表中使用的数据类型应该相同(或)您应该使用 cast 或 convert 函数来匹配这两个表中的数据类型

SQL 标准:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    相关资源
    最近更新 更多