3

私はテラデータが初めてです。以下のように作成した table に 1 から 1000 までの数字を挿入したいと思いtest_seqます。

create table test_seq(
    seq_id integer
);

このサイトで検索した後、数字を挿入するための再帰クエリを思いつきました。

insert into test_seq(seq_id)
with recursive cte(id) as (
    select 1 from test_dual
    union all
    select id + 1 from cte
    where id + 1 <= 1000
    )
select id from cte;

test_dual次のように作成され、単一の値のみが含まれます。(Oracle の DUAL のようなもの)

create table test_dual(
    test_dummy varchar(1)
);

insert into test_dual values ('X');

しかし、挿入ステートメントを実行すると、エラーが発生します。Failure 2616 Numeric overflow occurred during computation.

ここで何が間違っていましたか?integer数値 1000 を保持するのに十分なデータ型ではありませんか? また、テーブルを廃止できるようにクエリを作成する方法はありtest_dualますか?

4

1 に答える 1

7

単純に 1 を書き込むと、パーサーはそれに最適なデータ型 (BYTEINT) を割り当てます。BYTEINT の有効な値の範囲は -128 ~ 127 であるため、型キャストを INT に追加するだけです :-)

通常、Teradata の「SELECT 1;」ではダミーの DUAL テーブルは必要ありません。は有効ですが、パーサーがまだ FROM を要求する場合があります (理由は聞かないでください)。このトリックはうまくいくはずです:

SEL * FROM (SELECT 1 AS x) AS dt;

これでビューを作成できます:

REPLACE VIEW oDUAL AS SELECT * FROM (SELECT 'X' AS dummy) AS dt;

「SELECT 1 FROM oDUAL;」と説明します。は少しばかげているので、実際のテーブルの方が良いかもしれません。しかし、効率的なアクセス (= 単一 AMP/単一行) を得るには、次のように定義する必要があります。

CREATE TABLE dual_tbl(
    dummy VARCHAR(1) CHECK ( dummy = 'X') 
) UNIQUE PRIMARY INDEX(dummy); -- i remember having fun when you inserted another row in Oracle's DUAL :_)

INSERT INTO dual_tbl VALUES ('X'); 

REPLACE VIEW oDUAL AS SELECT dummy FROM dual_tbl WHERE dummy = 'X';

insert into test_seq(seq_id)
with recursive cte(id) as (
    select cast(1 as int) from oDUAL
    union all
    select id + 1 from cte
    where id + 1 <= 1000
    )
select id from cte;

ただし、この場合のようにデータが単一の AMP に存在する場合でも、再帰は連続しており、常に「すべての AMP ステップ」であるため、数値の範囲を取得する適切な方法ではありません。

値が 73414 (201 年) 未満の場合は、sys_calendar.calendar (または既知の一連の数字を持つその他のテーブル) を使用することをお勧めします。

SELECT day_of_calendar 
FROM sys_calendar.CALENDAR
WHERE day_of_calendar BETWEEN 1 AND 1000;

それ以外の場合は、CROSS 結合を使用します。たとえば、1 から 1,000,000 までの数値を取得するには:

WITH cte (i) AS 
 ( SELECT day_of_calendar
   FROM sys_calendar.CALENDAR
   WHERE day_of_calendar BETWEEN 1 AND 1000
 ) 
SELECT 
  (t2.i - 1) * 1000 + t1.i
FROM cte AS t1 CROSS JOIN cte AS t2;
于 2013-08-05T09:43:25.223 に答える