【发布时间】:2015-05-15 12:20:16
【问题描述】:
我对 sql 很陌生,我被卡住了。我正在尝试计算每个用户旅行的(每年)距离总和。我有一个具有以下结构的表(我们称之为 dist_table):
rowid user_name date LAT LONG
1 maria 2005-01-01 51.555 5.014
2 maria 2005-01-01 51.437 5.474
3 peter 2005-02-03 51.437 5.474
4 john 2005-02-03 51.858 5.864
5 maria 2005-02-04 51.858 5.864
6 john 2005-02-03 51.437 5.474
7 john 2006-02-04 0 0
8 john 2006-02-04 51.858 5.864
9 john 2006-02-04 51.858 5.864
10 john 2006-02-04 51.437 5.474
这是计算的中间步骤(只是为了澄清我的意思):
rowid user_name date LAT LONG distance
1 maria 2005-01-01 51.555 5.014 0
2 maria 2005-01-01 51.437 5.474 34.452
3 peter 2005-02-03 51.437 5.474 0
4 john 2005-02-03 51.858 5.864 0
5 maria 2005-02-04 51.858 5.864 54.012
6 john 2005-03-03 51.437 5.474 54.012
7 john 2006-02-04 0 0
8 john 2006-02-04 51.858 5.864 54.012
9 john 2006-02-04 51.858 5.864 0
10 john 2006-02-04 51.437 5.474 54.012
这是我需要的最终结果:
user_name date sum(distance)
maria 2005 88.464
peter 2005 0
john 2005 54.012
john 2006 108.024
我正在考虑使用这个公式(Haversine)来计算连续行之间的距离,然后将其相加:
SELECT user_name,date,dist_table.LAT,dist_table.LONG, 6373 * 2 * ASIN(SQRT(POWER(SIN((orig_latitude - abs(next_latitude)) * pi()/180 / 2),2)
+ COS(orig_latitude * pi()/180) * COS(abs(next_latitude) * pi()/180) * POWER(SIN((orig_longitude - next_longitude) * pi()/180 / 2),2) ))
AS distance FROM dist_table WHERE dist_table.LAT !=0 AND dist_table.LONG !=0;
但是,我无法弄清楚如何调用连续行。到目前为止,这是我试图弄清楚如何连接行时得到的结果:
SELECT user_name, date, LAT,
IFNULL( (
SELECT MAX( LAT )
FROM dist_table
WHERE user_name = t1.user_name
AND ( date < t1.date )
) ,0) AS next_latitude
FROM dist_table AS t1 ORDER BY user_name, date;
问题是对于每个用户,可以有多个行满足这个条件,这会选择最大值而不是前一个。此外,有时经度和/或纬度为 0,我需要忽略这些行。
我认为这可能会解决,如果我首先创建具有基于 user_name 和 date 的行顺序的列,然后在条件中添加类似 date+1 = t1.date 的内容。不幸的是,我在使用的服务器上的权限非常有限,因此这可能必须使用用户定义的变量来处理,但我不知道该怎么做。
我正在使用 mysql 5.6.19-log。
有人可以帮帮我吗?
【问题讨论】:
-
SQL 表代表 无序 集。没有“下一个”行的概念,除非您有一个指定排序的列。您是否有这样的列,可能是自动递增的 id 或日期/时间列?
-
请注意,LONG 是保留字。
-
是的,我知道 LONG,不幸的是,这是数据库中的名称,对此我无能为力。这就是为什么我将 dist_table.LONG 添加到名称中,这似乎可以解决计算时的问题。
-
@GordonLinoff 不幸的是,我没有。这些是我唯一可用的列。
-
@jonas 在这种情况下,您的问题在技术上是无法解决的——尽管有人可能会想出一个 hack。如果你能找到一些建立 PK 的方法,那就更好了。
标签: mysql