棘手的逻辑-SQL,Teradata

时间:2015-07-24 04:35:57

标签: sql database teradata

这是一个棘手的场景,我试图解决。 Table A1:有4列。此表在2天内保持更新一次。

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

请告诉我如何实现这一目标。

5 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

按日期排序.id,dates.date

忽略第一个值。这可能是从一开始的一点。

答案 2 :(得分: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

答案 3 :(得分:0)

你的Teradata版本是什么?

在TD14.10中有LAST_VALUE,可用于将NULL替换为先前的值:

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

答案 4 :(得分:-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