Sql-запрос, чтобы найти период даты между несколькими строками - PullRequest
5 голосов
/ 30 марта 2011

У меня есть таблица с тремя столбцами (City_Code | Start_Date | End_Date).
Предположим, у меня есть следующие данные:

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?

Заранее спасибо

Ответы [ 9 ]

1 голос
/ 31 марта 2011

Для 10g у вас нет опции SELECT 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.

1 голос
/ 30 марта 2011

Вы можете получить первую и последнюю дату проживания по городам, используя это:

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

, но проблема в том, что датой начала будет первая дата проживания в данном городе.

0 голосов
/ 31 марта 2011

у меня мало времени - но такое чувство, что вы можете использовать оконную функцию LAG, чтобы сравнить с предыдущей строкой и сохранить соответствующую дату начала из этой строки, когда город меняется, и не менять ее, когда город то же самое - это должно правильно сохранить диапазон.

0 голосов
/ 31 марта 2011

Если вы хотите рассчитать только длину последнего периода для последнего города проживания, то это, вероятно, примерно так:

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
0 голосов
/ 30 марта 2011
SELECT 
  MAX(t.duration) 
FROM (
       SELECT 
          (End_Date - Start_Date) duration 
       From 
           Table
) as t

Надеюсь, это сработает.

0 голосов
/ 30 марта 2011

Учитывая, что это Oracle, вы можете просто вычесть дату окончания и дату начала, чтобы получить число дней между ними.

Select City_Code, (End_Date - Start_Date) Days
From MyTable
Where Start_Date =  (
                        Select Max( T1.Start_ Date )
                        From MyTable As T1
                        )
0 голосов
/ 30 марта 2011

На SQL Server вы не могли бы использовать:

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

Это позволит получить период даты и город с самой последней датой окончания. Предполагается, что вы пытаетесь просто найти город, в котором человек недавно жил, отформатированный тире.

0 голосов
/ 30 марта 2011

Если вы используете SQL Server, вы можете использовать функцию DateDiff ()

DATEDIFF ( datepart , startdate , enddate )

http://msdn.microsoft.com/en-us/library/ms189794.aspx

EDIT

Я не знаю Oracle, но я нашел эту статью

0 голосов
/ 30 марта 2011

Если это MySQL, вы можете легко использовать

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

Имея разницу во времени в секундах, вы идете дальше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...