我有一个包含数字范围的 MySQL 数据库。它具有以下结构:
range_id,开始,结束
所有列都是 INT(10)。此外,还有一个名为 range_poly 的 Polygon 字段用于索引。
我想标记所有“外部”范围:不包含在数据库中另一个范围内的所有范围。例如:
range_id | start | end
1 | 1 | 2
2 | 4 | 5
3 | 1 | 10
在这种情况下,第三条记录是“外部范围”,因为它不包含在另一个范围内,但第一条和第二条记录不是因为它们完全包含在记录 3 中。为了实现这一点,我添加了一个名为 is_outer 的列是一个简单的 INT(1),用于指示范围是否包含在另一个范围内。我正在使用以下 php 脚本:
$result = mysql_query(mysql_real_escape_string("SELECT range_id, start FROM table;"), $db);
while($row = mysql_fetch_array($result))
{
$result2 = mysql_query(mysql_real_escape_string("SELECT range_id FROM table WHERE MBRCONTAINS( range_poly, POINTFROMWKB( POINT( ". $row['start'] ." , 0 ) ) ) ORDER BY (`end` - `start`) DESC LIMIT 1;"), $db);
$row2 = mysql_fetch_array($result2);
mysql_query(mysql_real_escape_string("UPDATE table SET is_outer = 1 WHERE range_id = ". $row2['range_id'] . ";"), $db);
}
这很好用,但我不禁觉得应该有一种更简单的方法来实现这一点。我似乎无法用一种纯粹的基于 SET 的查询来解决这个问题。或者,我可以使用 CURSOR 对此进行编码,但我想知道与 PHP 版本相比,性能是否会好得多。我的数据库有大约 370 万条记录,这解释了为什么性能非常重要。
我尝试使用子查询,但子查询中不允许使用 LIMIT。或者,我正在考虑自己加入表格,但我无法围绕正确的条件。