如果join id为null,则选择所有记录

时间:2013-03-20 10:56:37

标签: sql select null

情况:

Table1: id, 
Table2: id, table1_id
Table3: id, table2_id
user: id, table1_id (can be null), table2_id(can be null), table3_id(can be null)

Table1,Table2,Table3形成层次结构(对于单个table1行,thera在Table2中有很多行,而对于单个Table2行,表3中有很多行)

我需要从为所选用户分配的Table3中选择记录。 已分配表示用户记录中的ID匹配  (table1_id = Table1.id AND table2_id = Table2.id AND table3_id = Table3.id) 但是,如果用户记录中的值为空,则表示为相应表中的所有记录分配了用户。

if table1_id = null query should return all rows
elif table2_id = null query should return all rows where (table1_id = Table1.id)
elif table3_id = null query should return all rows where (table1_id = Table1.id AND table2_id = Table2.id 
elif query should return all rows where (table1_id = Table1.id AND table2_id = Table2.id AND table3_id = Table3.id)

我的主张:

declare @table1_id int
declare @table2_id int
declare @table3_id int

select @table1_id = table1_id, @table2_id = @table2_id, @table3_id = @table3_id 
from user where id = 5 (5 is parmeter)

select * from Table3 where
(@table1_id IS NULL OR @table1_id = 
       (select table1_id from Table2 where Table2.id = Table3.table2_id)) AND
(@table2_id IS NULL OR @table2_id = Table3.table2_id) AND
(@table3_id IS NULL OR @table3_id = Table3.id) 

这是不错的SQL查询?我能做得更好吗

1 个答案:

答案 0 :(得分:1)

您可以将这一切都放在一个查询中:

select table3.*
from table3 cross join
     (select table1_id, table2_id, table3_id 
      from user
      where id = 5
     ) const
where (const.table1_id is null or const.table1_id in (select table1_id from table2 where table2.id = table3.table2_id)) and
      (const.table2_id is null or const.table2_id = table3.table2_id) and
      (const.table3_id is null or const.table3_id = table3.id)

我将=替换为in,因为您可以从子选择中获得多个回复。

还有其他方法可以使用显式连接来表达这一点。但是,它们可能会导致重复的行,具体取决于表之间的关系。