#sql #match #union #teradata
#sql #совпадение #объединение #teradata
Вопрос:
Ниже приведен мой текущий код. Я не уверен, что лучший способ изменить это, чтобы получить нужные мне результаты.
SELECT
T1.SC,
T1.AN,
T1.DOFS_DATE,
T2.M_ID,
T3.OPDT,
T4.MARKER,
T5.E_DTE,
T5.E_TME,
T5.E_PST_DTE,
T5.E_AMT,
T5.E_NAR_O,
T5.E_NAR_T
FROM E_Base.AR_MyTable T1
LEFT JOIN E_Base.Translation T2
ON T1.SC = T2.SC
AND T1.AN = T2.AN
LEFT JOIN E_Base.BA T3
ON T2.M_ID = T3.M_ID
LEFT JOIN E_Base.APF T4
ON T3.M_ID = T4.M_ ID
AND MARKER = 54
LEFT JOIN U_DB.TEH_201804 T5
ON T2.M_ID = T5.M_ID
AND T1.DOFS_DATE = T5.E_PST_DTE
QUALIFY ROW_NUMBER() OVER (PARTITION BY T2.M_ID ORDER BY T2.ID_END_DATE DESC, T3.E_END_DATE DESC) = 1
Приведенный выше код работает. Однако это последнее левое соединение на T5, где мне нужна помощь.
В T1 каждому M_ID присвоено собственное значение DOFS_DATE, которое может быть любой датой в течение года, и я хочу, чтобы данные из T5 U_DB.TEH_201804 соответствовали дате. Однако 5 U_DB.TEH_201804 относится только к апрелю 2018 года. Существует 12 таблиц с одной и той же базой данных (201804, 201805, 201806 и т.д.), Которые все имеют одинаковые столбцы, но относятся к другому месяцу в году.
В идеале, я хочу один раз соединить столбцы из T5 по левой стороне, но выполнить поиск по всем 12 таблицам в базе данных, чтобы вернуть данные, в которых даты соответствуют.
Я думал об ОБЪЕДИНЕНИИ, но не уверен, как с этим работать.
Любая помощь была бы высоко оценена!
Спасибо
Комментарии:
1. Почему у вас есть 12 таблиц с точно такими же столбцами, но относящимися к другому месяцу в году вместо одной таблицы (которая могла бы быть разделена по месяцам)?
2. Это выше моего понимания. Все, что я знаю, это то, что в конце месяца данные архивируются в отдельную таблицу. Значительно усложняет мою жизнь!
Ответ №1:
Вы могли бы изменить свой код, связанный с таблицей t5, с помощью левого соединения в подзапросе, которое выбирает объединение all для всей необходимой вам пачки …… (я назвал подзапрос TT)
SELECT
T1.SC,
T1.AN,
T1.DOFS_DATE,
T2.M_ID,
T3.OPDT,
T4.MARKER,
TT.E_DTE,
TT.E_TME,
TT.E_PST_DTE,
TT.E_AMT,
TT.E_NAR_O,
TT.E_NAR_T
FROM E_Base.AR_MyTable T1
LEFT JOIN E_Base.Translation T2
ON T1.SC = T2.SC
AND T1.AN = T2.AN
LEFT JOIN E_Base.BA T3
ON T2.M_ID = T3.M_ID
LEFT JOIN E_Base.APF T4
ON T3.M_ID = T4.M_ ID
AND MARKER = 54
LEFT JOIN (
select *
FROM U_DB.TEH_201804
UNION ALL
select *
FROM U_DB.TEH_201805
UNION ALL
select *
FROM U_DB.TEH_201806
UNION ALL
select *
FROM U_DB.TEH_201807
UNION ALL
.....
) TT ON T2.M_ID = TT.M_ID
AND T1.DOFS_DATE = TT.E_PST_DTE
QUALIFY ROW_NUMBER() OVER (PARTITION BY T2.M_ID ORDER BY T2.ID_END_DATE DESC, T3.E_END_DATE DESC) = 1
Комментарии:
1. Это выглядит точно так, как я ищу. Однако, когда я иду запускать запрос, я получаю «Ошибка выбора. 2646. В myusername больше нет свободного места. Есть ли у вас какие-либо идеи, почему это было бы для этого запроса?
2. возможно, вы включаете слишком много строк и у вас возникла какая- то проблема.. я нашел вашу ошибку в Google kedar.nitty-witty.com/blog /…
3. Спасибо! База данных и таблицы, которые я просматриваю, огромны, поэтому, возможно, запрос слишком велик для моего выделения. Если я ищу только 6 месяцев, он работает отлично, поэтому я просто разделю его на два отдельных запроса и объединю данные вместе в Excel после. Огромное спасибо за помощь и быстрый ответ!
Ответ №2:
Трудно сказать без дополнительных деталей, таких как explain и данные шага QueryLog.
На основе ответа @scaisEdge:
Вы можете попытаться переместить первые два объединения в производную таблицу, чтобы применить ROW_NUMBER раньше (возможно, потому что вы выполняете только внешние объединения):
SELECT
dt.*,
T4.MARKER,
TT.E_DTE,
TT.E_TME,
TT.E_PST_DTE,
TT.E_AMT,
TT.E_NAR_O,
TT.E_NAR_T
FROM
(
SELECT
T1.SC,
T1.AN,
T1.DOFS_DATE,
T2.M_ID,
T3.OPDT
FROM E_Base.AR_MyTable T1
LEFT JOIN E_Base.Translation T2
ON T1.SC = T2.SC
AND T1.AN = T2.AN
LEFT JOIN E_Base.BA T3
ON T2.M_ID = T3.M_ID
QUALIFY Row_Number()
Over (PARTITION BY T2.M_ID
ORDER BY T2.ID_END_DATE DESC, T3.E_END_DATE DESC) = 1
) AS dt
LEFT JOIN E_Base.APF T4
ON dt.M_ID = T4.M_ID
AND MARKER = 54
LEFT JOIN
(
SELECT *
FROM U_DB.TEH_201804
UNION ALL
SELECT *
FROM U_DB.TEH_201805
UNION ALL
SELECT *
FROM U_DB.TEH_201806
UNION ALL
SELECT *
FROM U_DB.TEH_201807
UNION ALL
.....
) TT
ON dt.M_ID = TT.M_ID
AND dt.DOFS_DATE = TT.E_PST_DTE
Это также может помочь оптимизатору предоставить дополнительную информацию о диапазонах данных. Эти таблицы должны иметь КОНТРОЛЬНЫЕ ограничения, чтобы сообщить оптимизатору, что они содержат только данные за один месяц, если они не существуют, попробуйте добавить условие WHERE к каждому выбору, например WHERE E_PST_DTE BETWEEN DATE '2018-04-01' AND DATE '2018-04-30'
.
Конечно, всегда проверяйте Explain, действительно ли меняется план…