SQL自连接成对

use*_*267 8 sql t-sql sql-server join self-join

假设我有一个由像这样的条目组成的表

ID    Arrival Date    Arrival City    Departure Date    Departure City
1     Jun 27 2015     Berlin          Jun 20 2015       Paris
1     Jul 1 2015      Rome            Jun 29 2015       Berlin
1     Jul 30 2015     Vienna          Jul 15 2015       Rome
2     Jun 28 2015     Prague          Jun 23 2015       Vienna
2     Jul 1 2015      Rome            Jun 29 2015       Prague
2     Jul 30 2015     Vienna          Jul 15 2015       Moscow
...
Run Code Online (Sandbox Code Playgroud)

并且对于每个ID,我想将这些数据连接到自身,以便随后的观察Departure DateArrival Date成对分组 - 即离开与每个ID的先前到达配对.

在上面的例子中(为了方便起见,观察结果被排序),第2行将被附加到第1行,第3行到第2行,第5行到第4行以及第6行到第5行(因此产生4行字段ID Arrival Date Arrival City Departure Date Departure City Arrival Date2 Arrival City2 Departure Date2 Departure City2).

每个ID可能有三个以上的离开,因此需要一般方法.同时请注意,可以在数据孔那里Arrival CityDeparture City不匹配-例如,Arrival City第5行是不是Departure City第6行,但他们仍然应该合并.实际上,一个主要目标是更好地了解数据中有多少个洞.

Edu*_*Uta 8

解决方案是使用CTE并考虑两个连续行(由rowno标识)之间的差异始终为1(并且还考虑日期):

;WITH CTE AS (
SELECT
    rownum = ROW_NUMBER() OVER (ORDER BY t.ID, t.arrivalDate),
    t.ID,
    t.arrivalDate, 
    t.arrivalCity, 
    t.departureDate, 
    t.departureCity
FROM #test t
)
SELECT *
FROM CTE c1
JOIN CTE c2
ON c1.ID = c2.ID 
    AND c2.departureDate > c1.arrivalDate
    AND c2.rownum - c1.rownum = 1
GO

-- structure of the #test table
CREATE TABLE #test (
    ID int,
    arrivalDate date,
    arrivalCity varchar(30),
    departureDate date,
    departureCity varchar(30)
)
Run Code Online (Sandbox Code Playgroud)

SQL小提琴:SQLFiddle


sco*_*tyc 5

试试这个:

SELECT a.id
    ,a.arrival_date
    ,a.arrival_city
    ,a.departure_date
    ,a.departure_city
    ,b.arrival_date arrival_date_2
    ,b.arrival_city arrival_city_2
    ,b.departure_date departure_date_2
    ,b.departure_city departure_city_2
FROM triptable a
JOIN triptable b ON a.id = b.id
    AND a.departure_date = (SELECT min(departure_date) FROM so34815894 x WHERE x.departure_date > b.arrival_date AND x.id = b.id)
Run Code Online (Sandbox Code Playgroud)

根据您的评论编辑:

  • 找到上一个记录到达日期之后最早离开日期的记录,并且
  • 忽略了样本数据的第6条记录与第5条记录的到达城市不同的出发城市这一事实.