Проблема с извлечением данных из AS400 с использованием SQL - PullRequest
0 голосов
/ 26 мая 2020

Я пишу SQL запрос на экспорт данных из AS400 с использованием разных отношений. Я хочу написать это так, чтобы сократить время и повысить производительность моего ETL (у меня есть как минимум 29 миллионов строк для использования в моем ETL).

SQL:

SELECT  A.x1, A.x2, A.x3, A.x4, A.x5,
        (SELECT B.y1, B.y2, B.y3, C.w1 as w 
        FROM TEST1 AS B inner join TEST2 AS C ON ((C.w2=B.y4) and (C.w3=B.y5)) 
        where (B.y6 = 2)),
        E.q1

FROM TEST3 AS A
LEFT OUTER JOIN TEST1 AS B ON (A.x6 = B.y7)
LEFT OUTER JOIN TEST4 AS E ON ((A.x6 = E.q2) AND (A.x7 = E.q3))

Мне действительно нужна помощь в устранении этой ошибки

Я получил это исключение:

TITRE: Microsoft Visual Studio
Exception de HRESULT: 0xC0202009 Erreur sur Traitement [Источник [2 ]]: Код ошибки SSIS DTS_E_OLEDBERROR. Ошибка OLE DB в продукте. Код ошибки: 0x80004005. Отмена регистрации OLE DB недоступна. Источник: «Команда IBMDA400» Результат: 0x80004005 Описание: «SQL0412: Sous-Requête non admise, car plus d'une columns résultat Cause. . . . . : La sous-Requête d'un prédicat doit escapeir uniquement une colne résultat compareante lorsque l'autre opérande du prédicat est une expression simple. En effet, la sous-Requête peut extraire zéro, une ou plusieurs valeurs constituant une liste mais apparaissant dans une seule colne résultat. Que faire. . . : Модификация номеров обновлений по запросу для того, чтобы получить результаты по результатам исследования или заменить предварительные операции для получения списка выражений. ».

Ответы [ 2 ]

0 голосов
/ 30 мая 2020

Причина вашей ошибки в том, что подзапрос возвращает более одного столбца. AlwaysLearning уже сказал об этом.

Но следующая проблема будет в том, что ваш подзапрос возвращает несколько строк.

Если только

SELECT B.y1, B.y2, B.y3, C.w1 as w 
FROM TEST1 AS B inner join TEST2 AS C ON ((C.w2=B.y4) and (C.w3=B.y5)) 
where (B.y6 = 2)

не возвращает только одну строку. Обратите внимание, что подзапрос не имеет условий, которые коррелируют с внешним выбором. Использование псевдонима B в подзапросе не коррелирует его с внешним выбором, поскольку он переопределяется во внутреннем выборе в FROM TEST1 AS B. Это делает псевдоним локальным для подзапроса и скрывает использование B во внешнем выборе из подзапроса. Если это не то, что вы планировали, и даже если это было так, вы всегда должны следовать простому правилу в SQL, не используйте alises повторно.

0 голосов
/ 26 мая 2020

Вы можете использовать «табличное выражение» для присоединения дополнительных данных вместо «скалярного подзапроса».

Скалярные подзапросы ограничены одной строкой (ваша может возвращать несколько строк) и одним столбцом (ваш явно пытается вернуть более одного столбца).

Например, вы можете сделать:

SELECT  A.x1, A.x2, A.x3, A.x4, A.x5,
        f.y1, f.y2, f.y3, f.w,
        E.q1
FROM TEST3 AS A
LEFT OUTER JOIN TEST1 AS B ON (A.x6 = B.y7)
LEFT OUTER JOIN TEST4 AS E ON ((A.x6 = E.q2) AND (A.x7 = E.q3))
left join (
  SELECT B.y1, B.y2, B.y3, C.w1 as w 
  FROM TEST1 AS B -- you should avoid reusing the same alias B, but OK
  inner join TEST2 AS C ON ((C.w2=B.y4) and (C.w3=B.y5)) 
  where (B.y6 = 2)
) f on 1 = 1 -- what's the join condition? I assume you want all rows to match

ИЗМЕНИТЬ, ЧТОБЫ УПРОСТИТЬ ЗАПРОС

Вы выбираете все строки из таблицы A; это обязательно будет медленно. Тем не менее, поскольку ваши объединения являются равнозначными, они могут значительно выиграть от индексов; следующие индексы могут ускорить ваш запрос:

create index ix1 on TEST1 (y7, x1, x2, x3, x4, x5);

create index ix2 on TEST1 (y6, y1, y2, y3);

create index ix3 on TEST4 (q2, q3, q1);

create index ix4 on TEST2 (w2, w3, w1);
...