我是teradata的新手。我想在表test_seq
中插入数字1到1000,如下所示。
create table test_seq(
seq_id integer
);
在这个网站上搜索后,我想出了recusrive查询来插入数字。
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');
但是,当我运行insert语句时,我收到错误Failure 2616 Numeric overflow occurred during computation.
我在这里做错了什么? integer
数据类型不足以容纳数值1000吗?
另外,有没有办法编写查询,以便我可以取消test_dual
表?
答案 0 :(得分:7)
当您只编写1时,解析器会为其分配最佳匹配数据类型,即BYTEINT。 BYTEINT的有效值范围是-128到127,所以只需向INT添加一个类型转换: - )
通常在Teradata中不需要伪DUAL表,“SELECT 1;”是有效的,但在某些情况下,解析器仍然坚持使用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;