1

数値の範囲を含むMySQLデータベースがあります。次の構造になっています。

range_id、start、end

すべての列はINT(10)です。さらに、インデックス作成に使用されるrange_polyと呼ばれるポリゴンフィールドがあります。

すべての「外部」範囲にフラグを立てたい:データベース内の別の範囲に含まれていないすべての範囲。例えば:

range_id  |  start |  end
    1     |    1   | 2
    2     |    4   | 5
    3     |    1   | 10

この場合、3番目のレコードは別の範囲に含まれていないため「外部範囲」ですが、1番目と2番目のレコードはレコード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を使用できません。あるいは、自分でテーブルに参加することを考えていますが、適切な条件に頭を包むことができません。

4

1 に答える 1

0

私があなたの質問を正しく理解しているなら、あなたはすべての親(外側の範囲)を返したいと思うでしょう。

もしそうなら、このようなことを試してください:

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

そして、これがSQLFiddleです。

If you have duplicated data (7, 33,36) and (8, 33,36), and you want both to return, you can add this to your WHERE clause:

OR (t1.start = t2.start AND t1.end = t2.end)

Good luck.

于 2013-02-03T18:08:41.857 に答える