0

我使用修改后的预排序树将 GEO 位置存储在我的应用程序中的单个表 LOC_TABLE 中。例如,希腊的子树示例如下所示:

+-------+---------------+-----+-----+------+
| ID    | NAME          | LFT | RGT | TYPE |
+-------+---------------+-----+-----+------+
|    10 | Greece        | 100 | 200 |   3  |
|    20 | Crete Isl.    | 120 | 140 |   4  |
|    25 | Crete-Vamos   | 121 | 122 |   4  |
|    26 | Crete-Rethymno| 123 | 124 |   4  |
 ....
+-------+---------------+-----+-----+------+

TYPE列用于存储位置类型(3 - 国家,4 - 城市)。如您所见,Crete 存储为 city,其中包含其他城市(例如VamosRethymno)作为​​其子级。

我需要执行两种类型的查询:

1)获取特定父项下特定类型的所有位置。

2)获取特定父级下特定类型的所有顶级位置:仅Crete Isl.在查询希腊境内的城市时应返回提供的位置示例,因为Crete Isl.没有城市类型的父级,而城市VamosRethymno具有城市类型的父级 -Crete Isl.

在每种情况下执行最快的查询是什么?

对于第一种情况,我考虑使用两个查询(首先,获取希腊的 LFT 和 RGT,第二个获取类型 = 4 的所有位置,它们具有适当的 LFT 和 RGT)或使用某种连接来一步获取所有位置. 哪个是最好的方法?

对于第二种情况,我目前没有任何合适的想法。我尝试了简单的子选择:

select loc.* from LOC_TABLE loc 
where 4 not in 
(select TYPE from LOC_TABLE p 
    where p.lft < loc.lft AND p.rgt > loc.rgt) 
AND loc.LFT > 100 AND loc.RGT < 200;

但是太长了。

我不介意添加更多列并用一些值填充它们,这将有助于加快这两种类型的查询。但我需要快速获取数据。

谢谢。

4

2 回答 2

1

我会尝试这样的事情: -

SELECT b.*
FROM LOC_TABLE a
INNER JOIN LOC_TABLE b
ON a.LFT < b.LFT AND a.RGT > b.RGT
WHERE a.ID = 10
AND b.TYPE = 4

简单的加入。

对于你的第二个问题,也许是这样的。找到父级,然后从中找到正确类型下的所有记录。找到与此孩子相同类型的任何父母。如果找到,则忽略。

SELECT b.*
FROM LOC_TABLE a
INNER JOIN LOC_TABLE b ON a.LFT < b.LFT AND a.RGT > b.RGT
LEFT JOIN LOC_TABLE c ON c.LFT > b.LFT AND c.RGT < b.RGT AND b.TYPE = c.TYPE
WHERE a.ID = 10
AND b.TYPE = 4
AND c.ID IS NULL
于 2013-04-15T11:16:33.233 回答
1

ID对于具有给定 by的特定记录的城市和后代的所有记录:id,请使用

SELECT descendant.ID, descendant.NAME, descendant.TYPE 
FROM LOC_TABLE location
INNER JOIN LOC_TABLE descendant
    ON descendant.LFT > location.LFT AND descendant.RGT < location.RGT
WHERE location.ID = :id AND TYPE = 4

对于所有记录的城市和记录的子记录,使用IDgivien by :id,使用

SELECT child.ID, child.NAME, child.TYPE 
FROM LOC_TABLE location
INNER JOIN LOC_TABLE child
    ON child.LFT > location.LFT AND child.RGT < location.RGT
LEFT OUTER JOIN LOC_TABLE intermediate
    ON intermediate.LFT < child.LFT
    AND intermediate.RGT > child.RGT
    AND intermediate.LFT > location.LFT
    AND intermediate.RGT < location.RGT
WHERE location.ID = :id
AND child.TYPE = 4
AND intermediate.ID IS NULL

LEFT OUTER JOIN连同条件一起intermediate.ID IS NULL消除了那些记录,其中child有一个location是 的祖先的后代child

于 2013-04-15T11:06:48.957 回答