多列SQL分区

时间:2014-04-08 18:46:04

标签: sql-server sql-server-2012

我有以下GPS报告表:

Original Table

我希望通过Lat,Long对其进行分组并检索资源移动的顺序:

Expected Result

我几乎有以下代码:

  ;WITH dt AS(
  SELECT ROW_NUMBER() OVER (Partition By ROUND(Latitude,2), ROUND(Longitude, 2),         DATEPART(hh,[GPS Time])  ORDER BY [GPS Time]) AS RowNumber,  
 ID, ResourceID, Region, [GPS Time], ROUND(Latitude,2) AS Latitude, ROUND(Longitude, 2) AS Longitude 
 FROM [dbo].[GeofenceReport] WHERE TenantID=2 AND CAST([GPS Time] AS Date) = '2014-02-11' AND ResourceID = 'MH202 (B 9349 OI)'
)
  SELECT * FROM dt WHERE RowNumber = 1 ORDER BY [GPS Time] 

但是这将对所有出现的资源进行分组。我希望它按顺序分组。因此,如果资源离开位置A - 移动到位置B - 然后移动到位置C,然后再移动到位置A.

Example in SQL Fiddle

1 个答案:

答案 0 :(得分:3)

我认为你不能使用简单的排名功能来做到这一点。按时间排序并不能通过lat / lon为您提供所需的组ID,并且按地理位置排序没有多大意义。什么工作是创建一个标志,说明lat / lon是否已更改并使用此运行总和作为序列/组ID。然后,您可以按此分组以获得结果。

with cte as
(
  SELECT
    ID, ResourceID, Region, [GPS Time], Latitude, Longitude, 
    lag(LATITUDE, 1) over(order by [gps time]) as prev_LATITUDE,
    lag(LONGITUDE, 1) over(order by [gps time]) as prev_LONGITUDE
  FROM 
    [dbo].[GeofenceReport]
)
, cte2 as
(
  select
    ID, ResourceID, Region, [GPS Time], Latitude, Longitude, 
    SUM(
      -- 1 if location changed, 0 otherwise
      CASE WHEN 
        Latitude <> prev_Latitude 
        OR Longitude <> prev_Longitude THEN 1
      ELSE 0 END
    ) OVER(ORDER BY [GPS Time]) as seq -- running sum over time
  from cte
)
select 
  min(id) as id, min(region) as region, min([GPS Time]) as [GPS Time],
  min(Latitude) as Latitude, min(Longitude) as Longitude
from cte2
group by seq

您更新的SQL fiddle