更新不同列中的重复数据

时间:2013-04-29 23:59:46

标签: sql-server sql-server-2005

我有一张包含有关轨道的地理数据的表格,基本上有许多点用纬度/长坐标组成一条轨道。现在,我的问题是一些曲目“共享”点,我想在同一个表中的另一个字段中引用这些共享点。让我举例说明:

TrackName | PointNo | Lat | Long | SharedTrack | SharedPoint
------------------------------------------------------------
Track1    | 1       |-35.3| 100.4| null        | null
Track1    | 2       |-35.2| 100.5| null        | null
Track1    | 3       |-35.1| 100.6| null        | null
Track2    | 1       |-34.9| 100.8| null        | null
Track2    | 2       |-35.0| 100.7| null        | null
Track2    | 3       |-35.1| 100.6| null        | null

某些记录可能具有相同的 Lat Long 值,这就是我们所说的 SharedPoint 。所以现在,我必须更新所有记录,以便 SharedPoints 从具有最低 TrackName的Track中获取 Lat Long ...按照相同的例子,这将是:

TrackName | PointNo | Lat | Long | SharedTrack | SharedPoint
------------------------------------------------------------
Track1    | 1       |-35.3| 100.4| null        | null
Track1    | 2       |-35.2| 100.5| null        | null
Track1    | 3       |-35.1| 100.6| null        | null
Track2    | 1       |-34.9| 100.8| null        | null
Track2    | 2       |-35.0| 100.7| null        | null
Track2    | 3       |-35.1| 100.6| Track1      | 3

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

试试这个:

create table Track
(
    TrackName varchar(max)
    , PointNo int
    , Lat  decimal(9, 1)
    , Long decimal(9, 1)
    , SharedTrack   varchar(max) 
    , SharedPoint int
)

insert Track 
values ('Track1' , 1 , -35.3, 100.4, null , null)
, ('Track1' , 2 , -35.2, 100.5, null , null)
, ('Track1' , 3 , -35.1, 100.6, null , null)
, ('Track2' , 1 , -34.9, 100.8, null , null)
, ('Track2' , 2 , -35.0, 100.7, null , null)
, ('Track2' , 3 , -35.1, 100.6, null , null)
, ('Track3' , 3 , -35.1, 100.6, null , null)
, ('Track4' , 1 , -35.1, 100.6, null , null)

;with cte
as
(
    -- Find all the shared tracks first.
    select a.Lat, b.Long, a.TrackName, b.TrackName as 'LowTrackName'
    from Track a
    join Track b    on a.Lat = b.Lat and a.Long = b.Long 
                        and a.TrackName > b.TrackName
)
, cte_2
as
(
    -- Get the lowest TrackName 
    select Lat, Long, TrackName, min(LowTrackName) as 'MinTrackName'
    from cte
    group by Lat, Long, TrackName
)
, cte_3
as
(
    -- Get the matching PointNo for the lowest TrackName
    select a.Lat, a.Long, a.TrackName, a.MinTrackName, b.PointNo
    from cte_2 a
    join Track b    on a.Lat = b.Lat
                        and a.Long = b.Long
                        and a.MinTrackName = b.TrackName
)
update a
set SharedTrack = b.MinTrackName
    , SharedPoint = b.PointNo
from Track a
join cte_3 b        on  a.Lat = b.Lat
                        and a.Long = b.Long
                        and a.TrackName = b.TrackName
where SharedTrack is null
and SharedPoint is null