如何根据一组分层规则进行复杂的SQL选择?

时间:2013-03-22 02:22:34

标签: sql selection hierarchical

这就是我所拥有的:

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")

1 个答案:

答案 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,因此,请自行查找