【问题标题】:How to differentiate the continuous and non-continuous date ranges based on ID column如何根据 ID 列区分连续和非连续日期范围
【发布时间】:2021-10-12 22:58:17
【问题描述】:
ID  STRT_DT, ENT_DT 
1 9/14/2020,10/5/2020
1 10/6/2020,10/8/2020
1 10/9/2020,12/31/2199
2 7/14/2020,11/5/2020
2 11/21/2020,11/22/2020
2 11/23/2020,12/31/2199

观察ID 1和2的上述数据,属于1的日期范围是连续的,ID 2是不连续的。我需要提取在 SQL 中连续的 ID。 预期的 o/p :如果任何日期范围不连续(按 ID 分组),则不应进入 select 子句。所以SQL输出的期望是得到ID=1

查询使用:

SELECT tab.ID,TAB.STRT_DT,TAB.ENT_DT,
STRT_DT - MIN(ENT_DT) OVER (PARTITION BY ID ORDER BY ENT_DT ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS diff, 
ENT_DT - MAX(STRT_DT) OVER (PARTITION BY ID ORDER BY ENT_DT ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) AS diff2 
FROM  tabLE QUALIFY diff <> 1 OR diff2 <> -1

【问题讨论】:

  • 您使用的是 Oracle 还是 Teradata?
  • 你可以用ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING代替RANGE BETWEEN INTERVAL '1' DAY PRECEDING AND INTERVAL '1' DAY PRECEDING
  • @jarlh 我正在使用 Teradata
  • @WernfriedDomscheit Order by 子句不适用于 RANGE

标签: sql teradata teradata-sql-assistant


【解决方案1】:

您可以使用没有窗口功能的自连接。

select t1.id,
       t2.start_dt prev_start_dt, t2.end_dt prev_end_dt,
       t1.start_dt, t1.end_dt,
       to_date(t1.start_dt, 'MM/DD/YYYY') - to_date(t2.end_dt, 'MM/DD/YYYY') diff
from   t t1 inner join t t2 on t1.id = t2.id
where  to_date(t1.start_dt, 'MM/DD/YYYY') - to_date(t2.end_dt, 'MM/DD/YYYY') = 1
order by t1.id, t1.start_dt

结果:

ID  PREV_START_DT   PREV_END_DT START_DT    END_DT  DIFF
1   9/14/2020   10/5/2020   10/6/2020   10/8/2020   1
1   10/6/2020   10/8/2020   10/9/2020   12/31/2199  1
2   11/21/2020  11/22/2020  11/23/2020  12/31/2199  1

演示:https://dbfiddle.uk/?rdbms=oracle_18&fiddle=e20d48300f81e746826e44d8ee6982be


如果您只想获取所有行都继续的ID,您可以使用左连接查看已连接的行和未连接的行。

select t1.id
from   t t1 left join t t2 
            on t1.id = t2.id
            and to_date(t1.start_dt, 'MM/DD/YYYY') - to_date(t2.end_dt, 'MM/DD/YYYY') = 1
group by t1.id
having count(t1.id) - 1 = count(t2.id)

结果:

ID
1

演示:https://dbfiddle.uk/?rdbms=oracle_18&fiddle=85679be30f170e3728d7e8b0b0da533e

【讨论】:

  • 我只想选择具有连续日期范围的 ID。根据上面提供的数据样本。我想要一个在 select 子句中获取 ID=1 的 SQL。请帮忙
  • select distinct t1.id from t t1 inner join t t2 on t1.id = t2.id where to_date(t1.start_dt, 'MM/DD/YYYY') - to_date(t2.end_dt, 'MM/DD/YYYY') = 1 order by 1 这仅选择 id。另外,我认为ID 2的第二到第三也是继续的。
  • 如果任何日期范围不连续(按 ID 分组),则不应进入 select 子句。所以SQL输出的期望是得到ID=1
  • @Shankar 哦,我明白了。我附加了你想要的答案。
【解决方案2】:
select ID
from
 (
   select 
      ID, 
      -- flag non-continous ranges, i.e. previous end is not equal to the day before current start
      case when STRT_DT - 1
            <> LAG(ENT_DT) OVER (PARTITION BY ID ORDER BY STRT_DT)
           then 1
           else 0
      end as flag
   from table
 ) as dt
group by ID
having sum(flag) = 0 -- only continous ranges exist

【讨论】:

  • 这有效并解决了我的问题。感谢您的快速响应和您的时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
  • 2014-12-16
  • 2013-03-24
  • 2023-02-09
  • 1970-01-01
相关资源
最近更新 更多