web-dev-qa-db-ja.com

異なる列タイプを持つUNIONALL 2つのSELECT-期待される動作?

データ型が異なる2つのテーブルで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'をデータ型intに変換するときに変換に失敗しました。

しかし、規格では何が定義されていますか?

4
alex

すべてのクエリで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"に置き換えました-タイプミスだと思います。

3
Parado

T-SQL UNION ページから:

以下は、UNIONを使用して2つのクエリの結果セットを組み合わせるための基本的なルールです。

  • 列の数と順序は、すべてのクエリで同じである必要があります。
  • データ型には互換性がなければなりません。

1つのデータ型がVARCHARで、他のデータ型がINTEGERの場合、SQLServerは暗黙的にVARCHARINTEGERに変換しようとします(ルールは優先順位の表に記載されています) 。いずれかの行の変換が失敗した場合、クエリは失敗します。したがって、これは機能します。

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データ型の優先順位


そうは言っても、クエリを機能させるために、整数データをvarcharに明示的に変換できます(結果のデータ型はvarcharになります)。

4
Salman A

基本的なルールは-> 使用されるデータ型は2つのテーブルで同じである必要があります(または)キャストまたは変換関数を使用してこれらの2つのテーブルのデータ型と一致する必要があります

SQL標準:

1)列の数と順序は、すべてのクエリで同じである必要があります。
2)列のデータ型は互換性がある必要があります。まったく同じ型である必要はありませんが、SQLServerが暗黙的に変換できる型である必要があります。

1
Hell Boy