2009-12-18 52 views
1

我有一个定义时间间隔的表。查询以从表中选择时间间隔

_______________________________ 
| id | description | start_date | 
|____|_____________|____________| 
| 1 | First  | NULL | 
| 3 | Third  | 2009-12-18 | 
| 5 | Second  | 2009-10-02 | 
| 4 | Last  | 2009-12-31 | 
|____|_____________|____________| 

它只存储开始日期,结束日期是下一个日期之前的一天。

我想有下一个结果:

____________________________________________ 
| id | description | start_date | end_date | 
|____|_____________|____________|____________| 
| 1 | First  | NULL | 2009-10-01 | 
| 5 | Second  | 2009-10-02 | 2009-12-17 | 
| 3 | Third  | 2009-12-18 | 2009-12-30 | 
| 4 | Last  | 2009-12-31 | NULL | 
|____|_____________|____________|____________| 

我应该怎么写这个查询,因为行包含从其他行的值?

(我认为MySQL的函数DATE_SUB可能是有用的。)

回答

2
SELECT d.id, d.description, MIN(d.start_date), MIN(d2.start_date) - INTERVAL 1 
DAY AS end_date 
FROM start_dates d 
LEFT OUTER JOIN start_dates d2 ON (d2.start_date > d.start_date OR d.start_date IS NULL) 
GROUP BY d.id, d.description 
ORDER BY d.start_date ASC 
+0

返回重复的行 – 2009-12-18 19:00:54

+0

你会得到什么重复的行?一个id不止一行? GROUP BY应该避免这种情况... – 2009-12-18 19:19:51

+0

对不起,我错了。它正在工作。非常感谢。 – 2009-12-18 19:32:56

0

如果你正在使用PHP,只是计算脚本中的一个日期。这很容易。

如果没有,会是这样的:

SELECT ID,description,start_date,start_date-1 AS end_date FROM ... 

工作?

UPDATE:它的工作原理部分,因为它返回20091224的开始日期2009-12-25但对于像日期2009-12-01等

0

将无法​​正常工作尝试

Select d.Id, d.Description, d.Start_Date, 
     n.Start_Date - 1 EndDate 
    From Table d 
    Left Join Table n 
     On n.Start_Date = 
       (Select Min(Start_date) 
       From Table 
       Where Start_Date > Coalesce(d.Start_Date, '1/1/1900') 
+0

不工作:返回太多行 – 2009-12-18 19:01:43

+0

什么其他行是其返回。如果您的数据如上所述,则应在表中每行返回一行。 – 2009-12-18 21:47:30

+0

对于'start_date'和'end_date',第一行具有'NULL' – 2009-12-19 20:14:36

2

尝试

select id, description, start_date, end_date from 
    (
    select @rownum_start:[email protected]_start+1 rank, id, description, start_date 
    from inter, (select @rownum_start:=0) p 
    order by start_date 
) start_dates 
left join 
    (
    select @rownum_end:[email protected]_end+1 rank, start_date - interval 1 day as end_date 
    from inter, (select @rownum_end:=0) p 
    where start_date is not null 
    order by start_date 
) end_dates 
using (rank) 

其中inter是你的表

这实际上返回:

mysql> select id, description, start_date, end_date from ... 
+----+-------------+------------+------------+ 
| id | description | start_date | end_date | 
+----+-------------+------------+------------+ 
| 1 | First  | NULL  | 2009-10-01 | 
| 5 | Second  | 2009-10-02 | 2009-12-17 | 
| 3 | Third  | 2009-12-18 | 2009-12-30 | 
| 4 | Last  | 2009-12-31 | NULL  | 
+----+-------------+------------+------------+ 
4 rows in set (0.00 sec) 
+0

(+ 1)谢谢,它的作品。不过,我接受Peter Lang的解决方案,因为它更简单。 – 2009-12-18 19:32:00

+0

是的,如果我有选择,我更喜欢彼得的解决方案太:-) – 2009-12-18 19:40:24