Teradata 解析器问题
Teradata parser issue
我正在尝试执行以下查询,但出现错误
INSERT INTO TABLEA(
CUSTOMER_CT_KEY,
CUSTOMER_ST_KEY,
CUSTOMER_TEST_KEY,
JAN_AMT,
FEB_AMT,
MAR_AMT)
SELECT
A.CUSTOMER_CT_KEY,
A.CUSTOMER_ST_KEY,
A.CUSTOMER_TEST_KEY,
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '01'
THEN A.AAA_AMT
ELSE 0
END),
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '02'
THEN A.BBB_AMT
ELSE 0
END),
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '03'
THEN A.CCC_AMT
ELSE 0
END)
FROM TABLEB B, TABLEC C
WHERE B.DATECOL<= C.DATECOL
AND B.CUSTOMER_CT_KEY NOT IN
(SELECT FS_CUSTOMER_CT_KEY FROM TABLED WHERE REF_NBR = 'VALUE')
GROUP BY 1,2,3;
Insert failed. 3899: Internal Error in Teradata SQL parser
输出:
CUSTOMER_CT_KEY CUSTOMER_ST_KEY CUSTOMER_TEST_KEY JAN_AMT FEB_AMT MAR_AMT
123456789 541245812 541245812 114.00 524.00 62.00
658412457 632514257 632514257 0.00 12.00 214.00
中的总行数
TABLEA - EMPTY
TABLEB - 420,098,323
TABLEC - 1
TABLED - 218,074
INNER SUBQUERY - 5
当我尝试对子查询的值进行硬编码时,它起作用了。插入的行数:105,615,541
请指导我如何进一步进行。谢谢
如果您遇到这样的错误,您应该向 Teradata 支持发起一个事件。这是来自 Messages 手册:
3899 Internal error in the Teradata SQL Parser.
Explanation: The Teradata SQL Parser erred.
Generated By: CON, LEX, PAR, SYN, RES and OPT modules.
For Whom: System Support Representative.
Notes: This is usually caused by a request that the Teradata SQL Parser could not correctly process, yet it did not detect
an error.
Remedy: Save all relevant information and notify your support representative.
基本上原始查询想要从 TABLEB 和 TABLEC 中获取一些数据,过滤条件是您不想要 TABLED 中的记录,当 REF_NBR='VALUE'
正如 Tim 所建议的那样,一种可能的解决方法(当您向 Teradata 提出申请时,正如 dnoeth 所建议的那样)可能是使用连接编写 IN 过滤条件。
我对此类查询的建议如下:
SELECT
A.CUSTOMER_CT_KEY,
A.CUSTOMER_ST_KEY,
A.CUSTOMER_TEST_KEY,
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '01'
THEN A.AAA_AMT
ELSE 0
END),
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '02'
THEN A.BBB_AMT
ELSE 0
END),
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '03'
THEN A.CCC_AMT
ELSE 0
END)
FROM TABLEB B
JOIN TABLEC C
ON B.DATECOL<= C.DATECOL
LEFT JOIN (SELECT FS_CUSTOMER_CT_KEY FROM TABLED
WHERE REF_NBR = 'VALUE' ) AS D
ON B.CUSTOMER_CT_KEY=D.FS_CUSTOMER_CT_KEY
WHERE D.FS_CUSTOMER_CT_KEY is null
GROUP BY 1,2,3;
D子查询保存了过滤条件的所有记录(你要过滤掉的)。
"D.FS_CUSTOMER_CT_KEY is null" 条件确保只有 CUSTOMER_CT_KEY 没有出现在子查询 D 中的记录才会出现在结果集中。
测试解决方案
由于对提议的解决方案和实际的 OP 要求存在一些误解,我尝试准备一个基本的测试用例,以便我们可以使用它来更好地理解彼此的解决方案和角落案例。
create multiset volatile table TABLEB (
CUSTOMER_CT_KEY BIGINT,
CUSTOMER_ST_KEY BIGINT,
CUSTOMER_TEST_KEY BIGINT,
AAA_AMT decimal(38,18),
DATECOL date
)
no primary index
on commit preserve rows;
create multiset volatile table TABLEC (
DATECOL date
)
no primary index
on commit preserve rows;
create multiset volatile table TABLED (
FS_CUSTOMER_CT_KEY bigint,
REF_NBR VARCHAR(5)
)
no primary index
on commit preserve rows;
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (123456789, 541245812, 541245812, 111, '2016-01-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (123456789, 541245812, 541245812, 524, '2016-02-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (123456789, 541245812, 541245812, 63, '2016-03-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (777777777, 111222333, 444555666, 42, '2016-03-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (658412457, 632514257, 632514257, 0, '2016-01-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (658412457, 632514257, 632514257, 12, '2016-02-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (658412457, 632514257, 632514257, 214, '2016-03-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (777777777, 999888777, 666555444, 42, '2016-03-15');
insert into tablec ( DATECOL)
values ( '2016-04-01');
insert into tabled ( FS_CUSTOMER_CT_KEY, REF_NBR)
values ( 777777777, 'VALUE');
insert into tabled ( FS_CUSTOMER_CT_KEY, REF_NBR)
values ( 658412457, 'OK1');
insert into tabled ( FS_CUSTOMER_CT_KEY, REF_NBR)
values ( 658412457, 'OK2');
insert into tabled ( FS_CUSTOMER_CT_KEY, REF_NBR)
values ( 658412457, 'OK3');
select
B.CUSTOMER_CT_KEY,
B.CUSTOMER_ST_KEY,
B.CUSTOMER_TEST_KEY,
SUM(case when extract(MONTH from b.DATECOL)='01' then b.aaa_amt else 0 end) jan_amt,
SUM(case when extract(MONTH from b.DATECOL)='02' then b.aaa_amt else 0 end) feb_amt,
SUM(case when extract(MONTH from b.DATECOL)='03' then b.aaa_amt else 0 end) mar_amt
from tableb b, tablec c
where b.datecol<=c.datecol
and b.CUSTOMER_CT_KEY not in (select FS_CUSTOMER_CT_KEY from TABLED WHERE REF_NBR='VALUE')
group by 1,2,3;
select
B.CUSTOMER_CT_KEY,
B.CUSTOMER_ST_KEY,
B.CUSTOMER_TEST_KEY,
SUM(case when extract(MONTH from b.DATECOL)='01' then b.aaa_amt else 0 end) jan_amt,
SUM(case when extract(MONTH from b.DATECOL)='02' then b.aaa_amt else 0 end) feb_amt,
SUM(case when extract(MONTH from b.DATECOL)='03' then b.aaa_amt else 0 end) mar_amt
from tableb b
inner join tablec c
on b.datecol<=c.datecol
left join TABLED D
ON B.CUSTOMER_CT_KEY=D.FS_CUSTOMER_CT_KEY
AND D.REF_NBR<>'VALUE'
group by 1,2,3;
select
B.CUSTOMER_CT_KEY,
B.CUSTOMER_ST_KEY,
B.CUSTOMER_TEST_KEY,
SUM(case when extract(MONTH from b.DATECOL)='01' then b.aaa_amt else 0 end) jan_amt,
SUM(case when extract(MONTH from b.DATECOL)='02' then b.aaa_amt else 0 end) feb_amt,
SUM(case when extract(MONTH from b.DATECOL)='03' then b.aaa_amt else 0 end) mar_amt
from tableb b
inner join tablec c
on b.datecol<=c.datecol
left join (select FS_CUSTOMER_CT_KEY from TABLED where REF_NBR='VALUE' ) as D
ON B.CUSTOMER_CT_KEY=D.FS_CUSTOMER_CT_KEY
WHERE D.FS_CUSTOMER_CT_KEY is null
group by 1,2,3;
根据(有偏见且完全虚构的 :-) 数据,我得到了附加结果。
模拟原始查询
初始提议的模拟
模拟我目前的提议
(我已经告诉过你数据是有偏见和虚构的,对吧?:-))
OP 能否提供一些反馈或一些假数据以插入易变表中?
只是关于这个问题的更新。我已从 Teradata 支持部门获得澄清。在执行插入查询之前,必须执行以下语句。
diagnostic evlinterp on for session;
我正在尝试执行以下查询,但出现错误
INSERT INTO TABLEA(
CUSTOMER_CT_KEY,
CUSTOMER_ST_KEY,
CUSTOMER_TEST_KEY,
JAN_AMT,
FEB_AMT,
MAR_AMT)
SELECT
A.CUSTOMER_CT_KEY,
A.CUSTOMER_ST_KEY,
A.CUSTOMER_TEST_KEY,
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '01'
THEN A.AAA_AMT
ELSE 0
END),
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '02'
THEN A.BBB_AMT
ELSE 0
END),
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '03'
THEN A.CCC_AMT
ELSE 0
END)
FROM TABLEB B, TABLEC C
WHERE B.DATECOL<= C.DATECOL
AND B.CUSTOMER_CT_KEY NOT IN
(SELECT FS_CUSTOMER_CT_KEY FROM TABLED WHERE REF_NBR = 'VALUE')
GROUP BY 1,2,3;
Insert failed. 3899: Internal Error in Teradata SQL parser
输出:
CUSTOMER_CT_KEY CUSTOMER_ST_KEY CUSTOMER_TEST_KEY JAN_AMT FEB_AMT MAR_AMT
123456789 541245812 541245812 114.00 524.00 62.00
658412457 632514257 632514257 0.00 12.00 214.00
中的总行数
TABLEA - EMPTY
TABLEB - 420,098,323
TABLEC - 1
TABLED - 218,074
INNER SUBQUERY - 5
当我尝试对子查询的值进行硬编码时,它起作用了。插入的行数:105,615,541
请指导我如何进一步进行。谢谢
如果您遇到这样的错误,您应该向 Teradata 支持发起一个事件。这是来自 Messages 手册:
3899 Internal error in the Teradata SQL Parser.
Explanation: The Teradata SQL Parser erred.
Generated By: CON, LEX, PAR, SYN, RES and OPT modules.
For Whom: System Support Representative.
Notes: This is usually caused by a request that the Teradata SQL Parser could not correctly process, yet it did not detect
an error.
Remedy: Save all relevant information and notify your support representative.
基本上原始查询想要从 TABLEB 和 TABLEC 中获取一些数据,过滤条件是您不想要 TABLED 中的记录,当 REF_NBR='VALUE'
正如 Tim 所建议的那样,一种可能的解决方法(当您向 Teradata 提出申请时,正如 dnoeth 所建议的那样)可能是使用连接编写 IN 过滤条件。
我对此类查询的建议如下:
SELECT
A.CUSTOMER_CT_KEY,
A.CUSTOMER_ST_KEY,
A.CUSTOMER_TEST_KEY,
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '01'
THEN A.AAA_AMT
ELSE 0
END),
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '02'
THEN A.BBB_AMT
ELSE 0
END),
SUM(CASE WHEN EXTRACT(MONTH FROM A.DATECOL) = '03'
THEN A.CCC_AMT
ELSE 0
END)
FROM TABLEB B
JOIN TABLEC C
ON B.DATECOL<= C.DATECOL
LEFT JOIN (SELECT FS_CUSTOMER_CT_KEY FROM TABLED
WHERE REF_NBR = 'VALUE' ) AS D
ON B.CUSTOMER_CT_KEY=D.FS_CUSTOMER_CT_KEY
WHERE D.FS_CUSTOMER_CT_KEY is null
GROUP BY 1,2,3;
D子查询保存了过滤条件的所有记录(你要过滤掉的)。 "D.FS_CUSTOMER_CT_KEY is null" 条件确保只有 CUSTOMER_CT_KEY 没有出现在子查询 D 中的记录才会出现在结果集中。
测试解决方案
由于对提议的解决方案和实际的 OP 要求存在一些误解,我尝试准备一个基本的测试用例,以便我们可以使用它来更好地理解彼此的解决方案和角落案例。
create multiset volatile table TABLEB (
CUSTOMER_CT_KEY BIGINT,
CUSTOMER_ST_KEY BIGINT,
CUSTOMER_TEST_KEY BIGINT,
AAA_AMT decimal(38,18),
DATECOL date
)
no primary index
on commit preserve rows;
create multiset volatile table TABLEC (
DATECOL date
)
no primary index
on commit preserve rows;
create multiset volatile table TABLED (
FS_CUSTOMER_CT_KEY bigint,
REF_NBR VARCHAR(5)
)
no primary index
on commit preserve rows;
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (123456789, 541245812, 541245812, 111, '2016-01-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (123456789, 541245812, 541245812, 524, '2016-02-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (123456789, 541245812, 541245812, 63, '2016-03-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (777777777, 111222333, 444555666, 42, '2016-03-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (658412457, 632514257, 632514257, 0, '2016-01-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (658412457, 632514257, 632514257, 12, '2016-02-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (658412457, 632514257, 632514257, 214, '2016-03-15');
insert into tableb (CUSTOMER_CT_KEY, CUSTOMER_ST_KEY, CUSTOMER_TEST_KEY, AAA_AMT, DATECOL)
values (777777777, 999888777, 666555444, 42, '2016-03-15');
insert into tablec ( DATECOL)
values ( '2016-04-01');
insert into tabled ( FS_CUSTOMER_CT_KEY, REF_NBR)
values ( 777777777, 'VALUE');
insert into tabled ( FS_CUSTOMER_CT_KEY, REF_NBR)
values ( 658412457, 'OK1');
insert into tabled ( FS_CUSTOMER_CT_KEY, REF_NBR)
values ( 658412457, 'OK2');
insert into tabled ( FS_CUSTOMER_CT_KEY, REF_NBR)
values ( 658412457, 'OK3');
select
B.CUSTOMER_CT_KEY,
B.CUSTOMER_ST_KEY,
B.CUSTOMER_TEST_KEY,
SUM(case when extract(MONTH from b.DATECOL)='01' then b.aaa_amt else 0 end) jan_amt,
SUM(case when extract(MONTH from b.DATECOL)='02' then b.aaa_amt else 0 end) feb_amt,
SUM(case when extract(MONTH from b.DATECOL)='03' then b.aaa_amt else 0 end) mar_amt
from tableb b, tablec c
where b.datecol<=c.datecol
and b.CUSTOMER_CT_KEY not in (select FS_CUSTOMER_CT_KEY from TABLED WHERE REF_NBR='VALUE')
group by 1,2,3;
select
B.CUSTOMER_CT_KEY,
B.CUSTOMER_ST_KEY,
B.CUSTOMER_TEST_KEY,
SUM(case when extract(MONTH from b.DATECOL)='01' then b.aaa_amt else 0 end) jan_amt,
SUM(case when extract(MONTH from b.DATECOL)='02' then b.aaa_amt else 0 end) feb_amt,
SUM(case when extract(MONTH from b.DATECOL)='03' then b.aaa_amt else 0 end) mar_amt
from tableb b
inner join tablec c
on b.datecol<=c.datecol
left join TABLED D
ON B.CUSTOMER_CT_KEY=D.FS_CUSTOMER_CT_KEY
AND D.REF_NBR<>'VALUE'
group by 1,2,3;
select
B.CUSTOMER_CT_KEY,
B.CUSTOMER_ST_KEY,
B.CUSTOMER_TEST_KEY,
SUM(case when extract(MONTH from b.DATECOL)='01' then b.aaa_amt else 0 end) jan_amt,
SUM(case when extract(MONTH from b.DATECOL)='02' then b.aaa_amt else 0 end) feb_amt,
SUM(case when extract(MONTH from b.DATECOL)='03' then b.aaa_amt else 0 end) mar_amt
from tableb b
inner join tablec c
on b.datecol<=c.datecol
left join (select FS_CUSTOMER_CT_KEY from TABLED where REF_NBR='VALUE' ) as D
ON B.CUSTOMER_CT_KEY=D.FS_CUSTOMER_CT_KEY
WHERE D.FS_CUSTOMER_CT_KEY is null
group by 1,2,3;
根据(有偏见且完全虚构的 :-) 数据,我得到了附加结果。
模拟原始查询
初始提议的模拟
模拟我目前的提议
OP 能否提供一些反馈或一些假数据以插入易变表中?
只是关于这个问题的更新。我已从 Teradata 支持部门获得澄清。在执行插入查询之前,必须执行以下语句。
diagnostic evlinterp on for session;