这就是我所拥有的:
T1是来自复杂SQL的大量ID和总计。 TA,PF和BL是3个不同的表,用于保存不同的地址信息。
为了获得T1中每个ID的正确地址,需要遵循一组3个分层规则:
TA是第一个用T1.ID检查行存在的地址表。如果TA中存在一行,则获取地址并忽略检查表PF和BL。
PF是第二个地址表,用于检查TA是否从T1返回任何内容。如果PF中存在一行,则获取地址并忽略检查表BL。
BL是第3个地址表,用于检查PF是否从T1返回任何内容,如果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")
答案 0 :(得分: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,因此,请自行查找