0

这是我所拥有的:

T1 是来自复杂 SQL 的大量 ID 和总计。TA、PF 和 BL 是 3 个不同的表,用于保存不同的地址信息。

为了在 T1 中为每个 ID 获取正确的地址,需要遵循一组 3 条分层规则:

TA 是第一个使用 T1.ID 检查行是否存在的地址表。如果 TA 中存在一行,则获取地址并忽略检查表 PF 和 BL。

PF 是第二个地址表,用于检查我是否没有从 TA 返回任何带有 T1.ID 的信息。如果PF中存在一行,则获取地址并忽略检查表BL。

BL 是第三个地址表,用于检查我是否没有从 PF 返回任何具有 T1.ID 的内容,如果 BL 中存在一行,则获取地址。

现在我有如下代码,即使不使用 UNION 也可以单独运行很长时间!!!如何以有效的方式编写此逻辑?请帮忙!

select T1.ID, TA.ADDRESS,T1.TOTALS
from T1, TA
where T1.ID = TA.ID and TA.ADDRESS like "1"

UNION

select T1.ID, PF.ADDRESS,T1.TOTALS
from T1, PF
where T1.ID = PF.ID and PF.ADDRESS like "2"
and not exists(select 1
                from TA
               where TA.ID = T1.ID
                 and TA.ADDRESS like "1")
UNION

select T1.ID, BL.ADDRESS, T1.TOTALS
from T1, BL
where T1.ID = BL.ID and BL.ADDRESS like "3"
and not exists(select 1
                from TA
               where TA.ID = T1.ID
                 and TA.ADDRESS like "1")
and not exists(select 1
                from PF
               where PF.ID = T1.ID
                 and PF.ADDRESS like "2")
4

1 回答 1

0

首先,更改ADDRESS like "1"ADDRESS = "1". 在这种情况下,数据库引擎将能够使用 ADDRESS 上的索引(如果存在)。

not exist其次,如果你这样做,你可以摆脱:

select T1.ID, TA.ADDRESS,T1.TOTALS, TA.ADDRESS
from T1, TA
where T1.ID = TA.ID and TA.ADDRESS like "1"

UNION

select T1.ID, PF.ADDRESS,T1.TOTALS, PF.ADDRESS
from T1, PF
where T1.ID = PF.ID and PF.ADDRESS like "2"

UNION

select T1.ID, BL.ADDRESS, T1.TOTALS, BL.ADDRESS
from T1, BL
where T1.ID = BL.ID and BL.ADDRESS like "3"

ORDER BY 4

正如您在上面的查询中看到的那样,我已将 包含ADDRESS到选定列的列表中并按此列排序。我已从not exist查询中删除。这意味着将选择所有地址,按优先级排序

现在,你有两个选择:要么使用应用程序只抓取第一行,而忽略其他,或者,如果你不能修改应用程序代码,那么你需要使用 TOP(对于 SQL Server),LIMIT(对于 MySql) , ROW_NUM (for Oracle) 技术来获取前 n 行。您还没有标记您使用的 RDBMS,所以,请自行查找

于 2013-03-22T03:16:08.130 回答