Mysql 基于第二次查询结果标记行的SQL查询

Mysql 基于第二次查询结果标记行的SQL查询,mysql,sql,Mysql,Sql,我有一个MySQL数据库,其中包含一系列数字。其结构如下: 范围\u id,开始,结束 所有列都是INT(10)。此外,还有一个称为range_poly的多边形字段用于索引 我想标记所有“外部”范围:数据库中不包含在另一个范围内的所有范围。例如: range_id | start | end 1 | 1 | 2 2 | 4 | 5 3 | 1 | 10 在这种情况下,第三条记录是“外部范围”,因为它不包含在另一

我有一个MySQL数据库,其中包含一系列数字。其结构如下:

范围\u id,开始,结束

所有列都是INT(10)。此外,还有一个称为range_poly的多边形字段用于索引

我想标记所有“外部”范围:数据库中不包含在另一个范围内的所有范围。例如:

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);
}
这很好,但我忍不住觉得应该有一个更简单的方法来实现这一点。我似乎无法用一种纯粹的基于集合的查询来解决这个问题。或者,我可以使用游标编写代码,但我想知道与PHP版本相比,性能是否会更好。我的数据库大约有370万条记录,这解释了为什么性能非常重要


我尝试使用子查询,但子查询中不允许使用限制。或者,我正在考虑自己加入表格,但我无法理解正确的条件。

如果我正确理解您的问题,您希望返回所有父级(外部范围)

如果是这样,请尝试以下方法:

SELECT 
  t1.range_id
FROM YourTable t1
   LEFT JOIN YourTable t2 ON 
    t1.start >= t2.start AND t1.end <= t2.end AND t1.range_id <> t2.range_id
WHERE t2.range_id IS NULL

祝你好运。

如果我们有另一张唱片,比如说
(7,33,36)
?事实上,没有孩子的唱片也应该被退回。嘿,我可以从小提琴上看到它工作得很好,谢谢!然而,在我相当大的数据库中,这需要很长时间。我只是想知道是否有任何方法可以加快速度,比如制作索引或利用已经存在的空间索引?尝试标记覆盖所有范围的最小记录?数字实际上是IP地址的数字表示,我对更大的范围而不是子范围感兴趣。
OR (t1.start = t2.start AND t1.end = t2.end)