通过PHP / PDO从MySQL数据库中选择Distinct Rows

时间:2013-01-02 11:38:47

标签: php mysql pdo haversine

  

可能重复:
  How to prevent SQL injection in PHP?
  Select distinct rows from MySQL Database

嗨我有一个phonegap应用程序,可以在检测到路面变形(如坑洞和速度爆破)时存储纬度,经度,地址和严重程度。

到目前为止,通过PHP PDO将这些保存在数据库中根本不是问题。 PDO的设计方式是,如果报告的坑洞已经报告了10次(检查数据库中15米范围内的任何条目),那么就不会报告(即再次插入数据库)。此外,加载表面变形也不是问题,我使用Haversine公式来做到这一点,我传递用户的纬度和经度并获得一定距离内的值。

$stmt = $dbh->prepare("
  SELECT
    lat, lng,
    ( 6378160 * acos( cos( radians(?) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(?) ) + sin( radians(?) ) * sin( radians( lat ) ) ) ) AS distance
  FROM myTable
  HAVING distance > 0 
  ORDER BY distance
  LIMIT 0 , 30
");

我的问题是,由于可以报告10次相同的坑洞,我最终会将相同的坑洞报告回地图上的图表10次。我需要做的是,获取与用户相距一定距离的坑洼列表(使用半正式公式完成),然后从该列表中筛选出坑洼,以便我只得到明显的坑洼而不是相同的坑洼坑洞被退回10次。任何人都知道如何进行这样的过滤?任何人都可以告诉我如何在PHP / PDO中执行此操作或指向一些类似的教程(如果可用)?

以下是我需要做的简要说明:说我靠近坑洞A和坑洞B,说我有6个坑洞A报告,8个坑洞B报告(等等)在数据库中。通过使用hasrsine公式,我得到了坑洼A和坑洼B的报告的所有值(即14个结果)。我需要的是我得到了坑洞A报告的中点和坑洞B报告的中点(使用:http://www.geomidpoint.com/calculation.html)并返回2个结果(一个用于A,一个用于B)而不是14个结果

2 个答案:

答案 0 :(得分:1)

你必须分开坑洼和报告。首先查询GROUP BY lat, lng周围的坑洞,然后使用LIMIT 1查询每个坑洞的一个报告。

$rows = dbh_query("SELECT id FROM ... ");
foreach ($rows as $row)
{
    dbh_query("SELECT ... WHERE id = :id LIMIT 1", array('id' => $row['id']));
}

答案 1 :(得分:0)

我认为您有2个选项可供详细说明。不幸的是,两者都意味着一些并发症。

1)您应该始终在写作时将它们聚类,而不是编写多个观察。例如,如果您支持10米的空间粒度,那么每次新测量到达的距离小于现有记录10米时,您不会添加新的坑洞,而是更改平均值(纬度,经度,计数器)。最近的现有记录。这样,您最终会得到2个坑洼A和B的记录,因此您可以使用DISTINCT查询。

2)对于每个请求,您可以从现有表中获取15米范围内的所有记录,并在其上创建一个临时表,用于计算沿着道路轴的概率密度函数。同样,这需要选择一个粒度,可以在ROUND函数中模拟为十进制精度。例如,如果您有一个用于计算当前点和现有记录之间距离的存储函数,您可以写:

INSERT INTO `temppdf` (dist, pothole_id)
SELECT FROM `maintable`
ROUND(distance(@current_lat, @current_lon, maintable.lat, maintable.lon), -1), pothole_id
WHERE distance(@current_lat, @current_lon, maintable.lat, maintable.lon) < 15;

然后,您可以查询temppdf,查找每个坑洞的最大计数器行,如下所示:

SELECT pothole, MAX(cnt) as `peak` FROM
(SELECT DISTINCT pothole, COUNT(dist) as cnt FROM `temppdf` GROUP BY pothole, dist) as `subq`
GROUP BY pothole;

结果是计数器大于阈值的坑洼。

相关问题