【问题标题】:SQL - Convert a series of updated dates into rows of start and end datesSQL - 将一系列更新日期转换为开始和结束日期的行
【发布时间】:2013-01-15 19:48:29
【问题描述】:

我有一个属性记录表,其中包含客户列表、属性和日期。此表每月更新一次,其中包含所有客户的当前属性值。

id     attr_val     date
1      red          2012-01-01
1      red          2012-02-01
1      blue         2012-03-01
2      green        2012-01-01
2      green        2012-02-01
2      green        2012-03-01

我想重铸或转置此表,以便它列出每个属性值的开始和结束日期。这样我就可以选择任意日期并执行date between start_dt and end_dt 以获取该日期的值。

id     attr_val     start_dt       end_dt
1      red          2012-01-01     2012-02-28
1      blue         2012-03-01     NULL
2      green        2012-01-01     NULL

这可以通过单个 SQL 命令实现,还是我需要运行某种更复杂的脚本?目标环境是 Teradata,但我认为解决方案与平台无关...

【问题讨论】:

  • end_dt 似乎与您的示例数据无关。

标签: sql date version transpose


【解决方案1】:

这可能就是你想要的

SELECT id, attr_val, min(date) as start_dt, max(date) as end_dt
FROM tablename
GROUP BY id, attr_val

或者这个:

SELECT id, attr_val, min(date) as start_dt,CASE WHEN max(date) > min(date) THEN max(date) ELSE null END as end_dt
FROM tablename
GROUP BY id, attr_val

【讨论】:

  • 当属性从一个值更改为另一个值并再次返回时,min(date)、max(date) 解决方案将不起作用。记录会将属性日期范围显示为重叠...希望就这么简单...
  • @user548084 - 错误...好吧,那么你如何保持“会话”不同?
【解决方案2】:

一个很好的解决方案是相关子查询:

select id, attr_val, min(date) as start_date, end_date
from (select t.*,
             (select min(date) - 1 from t t2 where t2.id = t.id and t2.date > t.date and t2.attr_val <> t.attr_val
             ) as end_date
      from t
     ) t
group by id, attr_val, end_date

这会计算给定 id 和属性值的属性不同的下一个日期。比这个日期少一个是结束日期。当给定 id 的属性在连续行上具有相同的值时,它们都将获得相同的 end_date(即使为 NULL)。然后查询使用此结束日期将它们组合在一起。

【讨论】:

  • 啊,这就是end_dt 的来源。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 2017-10-10
  • 2020-10-05
  • 2022-01-23
  • 2022-12-01
相关资源
最近更新 更多