Объединение одного столбца из нескольких таблиц

#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, действительно ли меняется план…