2011-03-30 155 views
5

我有一个表,有三列(City_Code | Start_Date | End_Date)。
假设我有以下数据:
SQL查询找到多行之间的日期期间

New_York|01/01/1985|01/01/1987 
Paris|02/01/1987|01/01/1990 
San Francisco|02/01/1990|04/01/1990 
Paris|05/01/1990|08/01/1990 
New_York|09/01/1990|11/01/1990 
New_York|12/01/1990|19/01/1990 
New_York|20/01/1990|28/01/1990 

我想获取日期期间这人住在自己住处的最后一个城市。在这个例子中,New_York(09/01/1990-28/01/1990)只使用sql。我可以通过使用java处理数据来获得这段时间,但是使用纯sql可以做到这一点吗?

在此先感谢

+0

什么数据库产品和版本? – Thomas 2011-03-30 16:21:13

+0

Oracle数据库10g – nthed 2011-03-30 16:35:33

回答

0

如果它是MySQL,你可以很容易地使用

TIME_TO_SEC(TIMEDIFF(end_date, start_date)) AS `diff_in_secs` 

有在几秒钟的时间差,你再往前走。

0

在SQL Server上,你不能使用:

SELECT TOP 1 City_Code, Start_Date + "-" + End_Date 
FROM MyTable 
ORDER BY enddate DESC 

这将得到日期和城市的最新结束日期。 这是假设你正试图找到最近居住的城市,用短划线格式化。

+0

谢谢鲍勃。这是我第一次尝试答案,所以我仍然在学习如何正确发布。我的目标是获得足够的声誉,以便能够针对帮助我的其他问题投票解决一些问题。感谢您的建议! – Bsand 2011-03-30 16:30:07

1

你可以抓住按城市使用此居住的第一个和最后一个日期:

SELECT TOP 1 City_Code, MIN(Start_Date), Max(End_Date) 
FROM Table 
GROUP BY City_Code 
ORDER BY Max(End_Date) desc 

,但问题是,开始日期将居住在城市中的问题第一次约会。

+0

+1以便将此答案移动到列表的顶部。现在你需要考虑连续的条目。如果这是SQL Server,那么CTE可能是有序的。 – 2011-03-30 16:33:11

+0

使用的数据库是oracle 10g。 – nthed 2011-03-30 16:36:22

0

鉴于这是Oracle,您可以简单地减去结束日期和开始日期以获取中间的天数。

Select City_Code, (End_Date - Start_Date) Days 
From MyTable 
Where Start_Date = (
         Select Max(T1.Start_ Date) 
         From MyTable As T1 
         ) 
0
SELECT 
    MAX(t.duration) 
FROM (
     SELECT 
      (End_Date - Start_Date) duration 
     From 
      Table 
) as t 

我希望这会工作。

0

如果你想只计算最后一个周期长度居留的最后一个城市,那么它可能是这样的:

SELECT TOP 1 
    City_Code, 
    End_Date - Start_Date AS Days 
FROM atable 
ORDER BY Start_Date DESC 

但如果你的意思是包括这个人曾经住在各个时期出现这种情况是他们居住的最后一个城市一个城市,那么它更复杂一些,但不要太多:

SELECT TOP 1 
    City_Code, 
    SUM(End_Date - Start_Date) AS Days 
FROM atable 
GROUP BY City_Code 
ORDER BY MAX(Start_Date) DESC 

但上述方案最有可能返回它计算所有数据后,才最后一个城市信息城市。我们需要吗?不一定,所以也许我们应该使用另一种方法。也许是这样的:

SELECT 
    City_Code, 
    SUM(End_Date - Start_Date) AS Days 
FROM atable 
WHERE City_Code = (SELECT TOP 1 City_Code FROM atable ORDER BY Start_Date DESC) 
GROUP BY City_Code 
1

对于10g,你没有选择TOP n选项,所以你必须有点创意。

WITH last_period 
AS 
(SELECT city, moved_in, moved_out, NVL(moved_in-LEAD(moved_out, 1) OVER (ORDER BY city), 0) AS lead 
FROM periods 
WHERE city = (SELECT city FROM periods WHERE moved_out = (SELECT MAX(moved_out) FROM periods))) 
SELECT city, MIN(moved_in) AS moved_in, MAX(moved_out) AS moved_out 
FROM last_period 
WHERE lead >= 0 
GROUP BY city; 

这适用于您给出的示例数据集。它可以对大数据集进行一些优化,但给你一个工作示例,在Oracle 10g上进行测试。

0

我很短的时间 - 但这感觉就像你可以使用窗口函数LAG与上一行进行比较,并保留城市更改时该行的适当开始日期,并且当城市变为时不更改它相同 - 这应该正确地保持范围。