Teradata Получение значения переменной из нескольких строк

#case #teradata #min #partition

Вопрос:

У меня есть следующие переменные даты и суммы для разных дат. Мне нужна только одна строка на идентификатор, основанная на минимуме дат.

Данные, которые у меня есть:

  ID     Date         Code      Amt
 101    2/1/2018      A90       25
 101    2/2/2018      B90       15
 101    2/5/2018      A90       25
 102    2/1/2018      B90       10
 

Данные, которые мне нужны:

  ID     A90_Date     B90_Date    A90_Amt  B90_Amt
 101    2/1/2018      2/2/2018       25    15
 102                  2/1/2018             10        
 

Мой вопрос:

 Select ID, 
    min(case when Code='A90' then Date else Null end) as A90_Date,
    min(case when Code='B90' then Date else Null end) as B90_Date,
    min(case when Code='A90' then Amt else Null end) as A90_Amt,
    min(case when Code='B90' then Amt else Null end) as B90_Amt
  from Table 
  group by 1
 

Хотя это дает мне значения даты и суммы, я обеспокоен тем, являются ли они точными или нет из записей более 1 мм. Существует ли эффективный способ извлечения этих данных с помощью Qualify / Partition операторов Teradata ?

Заранее спасибо за вашу помощь.

Комментарии:

1. Почему это может быть неправильно? Это довольно стандартная условная агрегация.

Ответ №1:

Если суммы для одного и того же идентификатора/кода отличаются, вы можете получить неправильные результаты. Затем вы должны отфильтровать самую раннюю дату перед агрегированием, например

 with cte as
 (
   Select ID, Code, Date, Amt
   from Table 
   qualify row_number() over (partition by ID, Code order by date) = 1
 )   
Select ID, 
    min(case when Code='A90' then Date end) as A90_Date,
    min(case when Code='B90' then Date end) as B90_Date,
    min(case when Code='A90' then Amt  end) as A90_Amt,
    min(case when Code='B90' then Amt  end) as B90_Amt
from cte 
group by 1
 

В зависимости от ваших данных это может быть более эффективным:

 Select DISTINCT ID, 
    first_value(case when Code='A90' then Date end) over (partition by ID order by date) as A90_Date,
    first_value(case when Code='B90' then Date end) over (partition by ID order by date) as B90_Date,
    first_value(case when Code='A90' then Amt  end) over (partition by ID order by date) as A90_Amt,
    first_value(case when Code='B90' then Amt  end) over (partition by ID order by date) as B90_Amt  
from Table 
group by 1