我有一张预订表,其中所有服务预订列表中的预订详细信息保存如下:
id user_id booking_date booking_id
1 3 2017-01-10 booking1
2 3 2017-01-11 booking1
3 3 2017-01-12 booking1
4 3 2017-01-13 booking1
5 3 2017-01-14 booking1
6 4 2017-01-19 booking2
7 4 2017-01-20 booking2
8 4 2017-01-21 booking2
9 4 2017-01-22 booking2
10 3 2017-02-14 booking3
11 3 2017-02-15 booking3
我希望获得连续预订的开始和结束日期。 喜欢user_id 3有2个日期范围的预订日期
from `2017-01-10 to 2017-01-14`
然后经过一些记录
from `2017-02-14 to 2017-02-15`
答案 0 :(得分:2)
首先,我不认为获得这样的序列确实有意义。 ......但是,好的。
要在一个查询中执行此操作,将使用该数据进行编辑。所以我先添加一些像“group_id”或“order_id”这样的列。因此,您可以将一个ID保存到属于一起的所有订单。 只需迭代表,按ID升序并检查下一个(或最后一个)数据是否具有相同的user_id。
如果您拥有order_id列,则可以简单
SELECT MIN(booking_date), MAX(booking_date) FROM table GROUP BY order_id
答案 1 :(得分:1)
好的,没有人说这很容易......我们走吧。这是一个差距和岛屿问题。让我说它在postges sql中很容易解决
我将mysql变量应用于您的场景。
我在SQL Fiddle上解决了这个问题:
MySQL 5.6架构设置:
create table t ( user_id int, booking_date date );
insert into t values
( 3, '2017-01-10'),
( 3, '2017-01-11'),
( 3, '2017-01-12'),
( 3, '2017-01-13'),
( 3, '2017-01-14'),
( 4, '2017-01-19'),
( 4, '2017-01-20'),
( 4, '2017-01-21'),
( 4, '2017-01-22'),
( 3, '2017-02-14'),
( 3, '2017-02-15');
查询1 :
select user_id, min(booking_date), max(booking_date)
from (
select t1.user_id,
t1.booking_date,
@g := case when(
DATE_ADD(@previous_date, INTERVAL 1 DAY) <> t1.booking_date or
@previous_user <> t1.user_id )
then t1.booking_date
else @g
end as g,
@previous_user:= t1.user_id,
@previous_date:= t1.booking_date
from t t1, ( select
@previous_user := -1,
@previous_date := STR_TO_DATE('01/01/2000', '%m/%d/%Y'),
@g:=STR_TO_DATE('01/01/2000', '%m/%d/%Y') ) x
order by user_id, booking_date
) X
group by user_id, g
<强> Results 强>:
| user_id | min(booking_date) | max(booking_date) |
|---------|-------------------|-------------------|
| 3 | 2017-01-10 | 2017-01-14 |
| 3 | 2017-02-14 | 2017-02-15 |
| 4 | 2017-01-19 | 2017-01-22 |
解释嵌套查询为每个范围计算group code
(g
)。外部查询获取每个组的最大值和最小值。