#sql #teradata
#sql #teradata
Вопрос:
Я пытаюсь выполнить приведенный ниже запрос, но получаю сообщение об ошибке
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
Пожалуйста, подскажите мне, как действовать дальше. Спасибо
Комментарии:
1. Пожалуйста, включите полные инструкции select и insert вместе с некоторыми примерами данных.
2. @TimBiegeleisen Спасибо за ваш ответ. Я включил инструкцию Select и пример вывода. Я попробовал внутреннее соединение в Date col, и оно сработало, но левое соединение не сработало. Я не получаю желаемый результат, и подзапрос выдаст от 4 до 5 строк.
3. Работает ли Select без Insert? Кстати,
EXTRACT
возвращает целое число, которое лучше использовать1
вместо'01'
.4. Если это может помочь, я приложил к своему ответу некоторые базовые данные CREATE TABLE INSERT для тестирования различных решений. Очевидно, что данные являются фиктивными и предвзятыми (это заставляет мое решение работать :-)), но это может послужить основой для того, чтобы OP более «практично» выразил свои сомнения.
5. Просто интересно: если в базовых таблицах нет какой-то необычной функции или какого-то странного параметра конфигурации на уровне экземпляра, это кажется довольно обычным запросом. Может быть, каким-то образом словарь данных «поврежден»? В этом случае, если он ограничен только одним из этих объектов, если вы создадите «клоны» всех объектов и запустите запрос к ним, он, скорее всего, будет запущен (и у вас будет способ узнать, что такое поврежденный объект). Однако, также, если это так, я бы дождался запроса, а НЕ отбрасывал и создавал исходные объекты.
Ответ №1:
Если вы получаете подобную ошибку, вам следует открыть инцидент со службой поддержки Teradata. Это из руководства по сообщениям:
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.
Комментарии:
1. Да, как вы и предлагали, я сообщил своей службе поддержки. Надеюсь, что-то должно появиться.
Ответ №2:
По сути, исходный запрос хотел получить некоторые данные из TABLEB и TABLEC с условием фильтра, при котором вам не нужны записи, которые находятся в ТАБЛИЦЕ, когда REF_NBR=’VALUE’
Как предложил Тим, возможным обходным путем (пока вы отправляете запрос в Teradata, как предложил dnoeth) может быть запись условия IN filter с помощью join .
Мое предложение для такого запроса заключается в следующем:
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.FS_CUSTOMER_CT_KEY равно нулю» гарантирует, что в результирующем наборе появятся только записи, чей 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 дать некоторую обратную связь или некоторые поддельные данные для вставки в изменяемые таблицы?
Комментарии:
1. Большое вам спасибо за ваши усилия. Я попытался выполнить ваш запрос. К сожалению, он выдает ту же ошибку.
Ответ №3:
Просто обновление по этой проблеме. Я получил разъяснение от службы поддержки Teradata. Перед выполнением запроса Insert необходимо выполнить следующую инструкцию.
diagnostic evlinterp on for session;