SQL:查找日期和条件之间的中间结果
Posted
技术标签:
【中文标题】SQL:查找日期和条件之间的中间结果【英文标题】:SQL: Finding middle result between dates and Criteria 【发布时间】:2018-06-16 15:41:47 【问题描述】:我必须找到并标记满足以下条件的客户,但我正在努力想出一种在 SQL 中而不是在 Excel 中手动执行此操作的方法。
客户必须满足以下条件:
-
入住Motel A
离开A后1天内入住Motel B(Motel B不能> 30天)
离开B后1天内返回Motel A
开始日期和结束日期必须相同或 +1 天才能考虑到帐单延迟
我们想为汽车旅馆 B 标记销售 ID #(对所有人都是唯一的)。
+--------+---------+----------+------------+------------+
| Cus ID | Sale ID | Motel ID | SDate: | EDate: |
+--------+---------+----------+------------+------------+
| 1 | 1234 | MA | 2017-01-01 | 2017-01-07 |
| 1 | 1435 | MB | 2017-01-07 | 2017-01-10 |
| 1 | 1562 | MA | 2017-01-10 | 2017-01-15 |
+--------+---------+----------+------------+------------+
在这里,我们将销售 ID:1435 标记为有效条件
+--------+---------+----------+------------+------------+
| Cus ID | Sale ID | Motel ID | SDate: | EDate: |
+--------+---------+----------+------------+------------+
| 2 | 3456 | MA | 2017-01-01 | 2017-01-07 |
| 2 | 3588 | MB | 2017-01-09 | 2017-02-15 |
| 2 | 3648 | MA | 2017-02-16 | 2017-02-17 |
+--------+---------+----------+------------+------------+
由于 #3588 超过 30 天,此失败,不应标记
+--------+---------+----------+------------+------------+
| Cus ID | Sale ID | Motel ID | SDate: | EDate: |
+--------+---------+----------+------------+------------+
| 1 | 1234 | MA | 2017-01-01 | 2017-01-07 |
| 1 | 1435 | MB | 2017-01-07 | 2017-01-10 |
| 1 | 1562 | MA | 2017-01-10 | 2017-01-15 |
| 1 | 1580 | MB | 2017-01-15 | 2017-01-20 |
| 1 | 1590 | MA | 2017-01-21 | 2017-01-22 |
+--------+---------+----------+------------+------------+
这个会标记 2 #1435 和 #1580
+--------+---------+----------+------------+------------+
| Cus ID | Sale ID | Motel ID | SDate: | EDate: |
+--------+---------+----------+------------+------------+
| 1 | 4555 | MA | 2017-01-01 | 2017-01-07 |
| 1 | 4803 | MB | 2017-01-09 | 2017-01-10 |
| 1 | 5238 | MA | 2017-01-10 | 2017-01-15 |
+--------+---------+----------+------------+------------+
这个失败,因为在 #4555 和 #4803 之间有 2 个间隔日期,不应标记
非常感谢任何建议或帮助。我可以通过 Excel 手动执行此操作,但要执行数百万或记录数过多的操作太耗时了。
如果这很重要,我正在使用 Aginity Netezza SQL。
【问题讨论】:
【参考方案1】:您可以使用lead()
和lag()
获得“上一个”和“下一个”停留。我认为您的条件变成了以下where
条件:
select t.*
from (select t.*,
lag(edate) over (partition by cusid order by sdate) as prev_edate,
lead(sdate) over (partition by cusid order by sdate) as next_sdate,
lag(motelid) over (partition by cusid order by sdate) as prev_motelid,
lead(motelid) over (partition by cusid order by sdate) as next_motelid
from t
) t
where prev_motelid = next_motelid and
prev_edate in (sdate, sdate - interval '1 day') and
next_sdate in (edate, edate + interval '1 day');
我不知道您所说的“(汽车旅馆 B 不能 > 30 天)”是什么意思。如果那是中间Motel的持续时间,那么这很容易添加到条件中。
【讨论】:
感谢您的回复。当我在 MA: 20160322--20160327 和 MB: 20160327--20160331 和 MA: 20160331--20160407 上尝试此代码时,它返回了 MA: 20160331--20160407。满足条件时,结果应仅返回 MB。 @Snoobie 。 . . “A”之后必须有另一条记录。 我调整了你的 where 子句并让它工作。非常感谢您的指导!你为我节省了几个小时的工作时间!以上是关于SQL:查找日期和条件之间的中间结果的主要内容,如果未能解决你的问题,请参考以下文章