2011-03-30 157 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與上一行進行比較,並保留城市更改時該行的適當開始日期,並且當城市變爲時不更改它相同 - 這應該正確地保持範圍。