2015-07-24 6 views
2

Вот сложный сценарий, который я пытаюсь решить. Table A1: имеет 4 столбца. И эта таблица обновляется раз в 2 дня.Tricky logic -SQL, Teradata

id name fav_color date 
2051 joe white  07/21 
2052 John green  07/21 

После 2 дней записи обновляются и table A1 выглядит следующим образом.

id name fav_color date 
2051 joe blue  07/23 
2052 Rick green  07/23 

Table A2: это таблица истории, которая фиксирует все изменения делаются для table A1.

id updated_column update_dt old_value new_value 
2051 fav_color  07/23  white  blue 
2052 Name    07/23  John  Rick 

Теперь бизнес хочет увидеть ежемесячный снимок таблицы A1 к концу месяца. В основном я хочу ежемесячный снимок, подобный этому.

id name fav_color date 
2051 joe white  07/21 
2051 joe blue  07/23 
2052 John green  07/21 
2052 Rick green  07/23 

Просьба сообщить мне, как этого достичь.

+0

Являются ли эти примеры столбцов, или это реально? –

+0

Сколько записей вы ожидаете в таблицах A1 и A2? –

+1

Вы также сохраняете старое значение даты в столбце истории? Потому что, если вы этого не сделаете, нет способа узнать, что значение 'old_value' было действительным в эту конкретную дату, и я не вижу способа получить нужный результат. –

ответ

0
SELECT id,name,fav_color,date 
FROM tableA1 

UNION ALL 

SELECT tableA2.id, 
     CASE WHEN tableA2.updatedColumn ='name' 
      THEN tableA2.oldValue 
      ELSE tableA1.name END, 
     CASE WHEN tableA2.updatedColumn ='fav_color' 
      THEN tableA2.oldValue 
      ELSE tableA1.fav_color END, 
     tableA2.update_dt 
FROM tableA2 
INNER JOIN tableA1 ON tableA2.id=tableA1.id 
ORDER BY id 
+0

Это не работает. Команда else в обоих случаях возвращает текущее значение, но оно должно показывать неизмененное значение в этот момент времени. –

-1

Попробуйте этот.
select * from ( select id,name,fav_color,date1 from Table1 union all select t2.id, Case t2.updated_column when 'Name' then t2.new_value else t1.name End as name, Case t2.updated_column when 'fav_color' then t2.new_value else t1.fav_color End as fav_color, t2.update_dt as date1 from Table2 t2 Inner Join Table1 t1 on t1.id = t2.id )A order by 1 Asc

0

очень примитивно, медленно и, вероятно, неполный путь, который должен более или менее вернуть то, что вам нужно:

SELECT 
    dates.id, 
    dates.date, 
    (SELECT TOP (1) name.new_value 
    FROM A2 name 
    WHERE name.id = dates.id and name.date <= dates.date and name.updated_column = 'name') as name, 
    (SELECT TOP (1) favcol.new_value 
    FROM A2 favcol 
    WHERE favcol.id = dates.id and favcol.date <= dates.date and favcol.updated_column = 'fav_color') as fav_color 
FROM A2 dates 

заказ dates.id, dates.date

Очень первые значения игнорируются. Вероятно, это нужно начинать.

0

Есть много зависимостей, но что-то подобное может это сделать.

select 
name.id 
, name.name 
, color.fav_color 
, color.update_dt 
from 
(select 
id 
,update_dt 
,new_value 
from a2 
where update_column = 'fav_color') color 
join 
(select 
id 
,update_dt 
,new_value 
from a2 
where update_column = 'name') name 
on color.id = name.id and color.update_dt = name.update_dt 
order by color.update_dt, name.id 
0

Какой у вас релиз Teradata?

В TD14.10 есть LAST_VALUE, который может быть использован для замены NULLs с предыдущим значением:

SELECT 
    id, 
    LAST_VALUE(name IGNORE NULLS) 
    OVER (PARTITION BY id 
     ORDER BY datecol DESC) AS name, 
    LAST_VALUE(fav_color IGNORE NULLS) 
    OVER (PARTITION BY id 
     ORDER BY datecol DESC) AS fav_color, 
    MAX(datecol) -- date of change, NULL for the first version 
    OVER (PARTITION BY id 
     ORDER BY datecol DESC 
     ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) AS detail 
FROM 
(
    SELECT id, NAME, fav_color, DATE '9999-12-31' AS datecol -- current version 
    FROM a1 

    UNION ALL 

    SELECT -- previous versions 
     id, 
     MAX(CASE WHEN updated_column = 'name' THEN old_value END) AS name, 
     MAX(CASE WHEN updated_column = 'fav_color' THEN old_value END) AS fav_color, 
     update_dt 
    FROM a2 
    GROUP BY id, update_dt 
) AS dt