SQL: 查找日期和标准之间的中间结果
SQL: Finding middle result between dates and Criteria
我必须找到并标记满足以下条件的客户,但我正在努力想出一种在 SQL 中而不是在 Excel 中手动完成的方法。
客户必须满足此条件:
- 入住汽车旅馆A
- 离开A后1天内入住汽车旅馆B(汽车旅馆B不能>30天)
- 离开B后1天内返回汽车旅馆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 之间有两个间隔日期,不应该被标记
非常感谢任何建议或帮助。我可以通过 Excel 手动执行此操作,但要对数百万或记录执行此操作太耗时了。
我正在使用 Aginity Netezza SQL 如果这很重要的话。
您可以使用 lead()
和 lag()
来获得 "previous" 和 "next" 停留。我认为你的条件变成了以下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的时长,那么这很容易加入条件。
我必须找到并标记满足以下条件的客户,但我正在努力想出一种在 SQL 中而不是在 Excel 中手动完成的方法。
客户必须满足此条件:
- 入住汽车旅馆A
- 离开A后1天内入住汽车旅馆B(汽车旅馆B不能>30天)
- 离开B后1天内返回汽车旅馆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 之间有两个间隔日期,不应该被标记
非常感谢任何建议或帮助。我可以通过 Excel 手动执行此操作,但要对数百万或记录执行此操作太耗时了。
我正在使用 Aginity Netezza SQL 如果这很重要的话。
您可以使用 lead()
和 lag()
来获得 "previous" 和 "next" 停留。我认为你的条件变成了以下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的时长,那么这很容易加入条件。