sql-server - SQL 多列分区

标签 sql-server sql-server-2012

我有以下 GPS 报告表:

Original Table

我希望按纬度、经度对其进行分组并检索资源移动的顺序:

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

最佳答案

我认为您无法使用简单的排名功能来做到这一点。按时间排序不会按纬度/经度为您提供所需的组 ID,按地理位置排序也没有多大意义。可行的方法是创建一个标志,说明纬度/经度是否发生变化,并将其运行总和用作序列/组 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

关于sql-server - SQL 多列分区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22945672/

相关文章:

sql - SQL Server 2012 中列存储索引中列的顺序是否重要

sql-server - 使用 TSQL 的按位操作,如旋转、选择性位反转

java - 将大型论坛数据从一个系统迁移到另一个系统

sql - 为什么 SQL Server 中的输出不同而 Oracle 中的输出相同?

json - 如何使用 TSQL 将 JSON 列解析为表

c# - SQL Server检索数据,数据获得了额外的空间

sql - 如何使用插入选择语句插入下一个最大值

sql - 用值替换 NULL

sql - 将值放入 SQL 列字段内的列表中

c++ - 多个应用程序之间的数据库状态