T-SQL - 如何编写条件连接

Cor*_*ett 44 t-sql join

我有一个包含许多参数的存储过程.我想编写我的查询,以便它与某些表连接,但仅当特定参数具有值时.举个例子:我有一个Person表.还有一个Address表,其中包含Person Addresses和一个包含Person Groups的Groups表.两者都是与Person表的一对多关系.我的存储过程有一个@AddressID参数和一个@GroupID参数.

查询始终只返回Person表中的字段.如果两个参数都没有值,则查询应返回Person表中的所有记录.如果提供了@AddressID参数,则它应仅返回在Address表中具有匹配记录的记录,并忽略Groups表.如果提供了@GroupID参数,则它应仅返回在Groups表中具有匹配记录的记录,并忽略Addresses表.如果提供了两个参数,那么它应该只显示两个表中具有匹配记录的记录.合理?

有一种简单的方法可以解决这个问题吗?

谢谢,科里

Qui*_*son 44

如果我理解正确,这听起来就像你的加入条件相同,
ON ((@AddressID IS NOT NULL) AND (alias.column = @AddressID))并且同样适用于团体加入.

我有时使用这种条件连接.

  • How is this correct? The inner join will return nothing if `@AddressID` is NULL (20认同)
  • @hidarikani当`@ AddressID`为NULL时,应该使用`LEFT OUTER JOIN`(而不是`INNER JOIN`)返回值。 (3认同)

Rem*_*anu 25

简单的方法实际上不是好的解决方案.听起来很糟糕,最好的解决方案是在代码和单独的查询中使用显式IF:

IF (condition) 
  SELECT ... FROM Person WHERE ...
ELSE IF (otherCondition)
  SELECT ... FROM Person JOIN ... ON ... WHERE ...
ELSE IF (moreCondition)
  SELECT ... FROM Persons JOIN ... JOIN ... WHERE ...
Run Code Online (Sandbox Code Playgroud)

这样做的原因是,如果您尝试构建一个匹配所有三个(或更多)条件的单个查询,则引擎必须生成一个适用于所有条件的单个查询计划.在T-SQL中,一个语句等于一个计划.请记住,为任何变量值创建了针对通用案例的计划,因此结果总是非常非常糟糕的计划.

虽然是违反直觉的,对任何程序员来说似乎都是一个可怕的解决方案,但这就是数据库的工作方式.99.99%的时间这不是问题的原因是,在尝试了你所要求的内容并看到它必须做什么之后,开发人员很快就会明白并修改他们的需求,这样他们就不必运行可选择加入的查询基于运行时变量值;)

  • LINQ2SQL可能出乎意料地更适合这样的事情,因为查询表达式的本质是完全成熟的对象,可以被操作和改进,请参阅http://stackoverflow.com/questions/1849005/converting-conditional-built -sql-where子句 - 进入 - LINQ/1849041#1849041 (2认同)

dot*_*joe 7

是的,这很简单.在地址和组上留下联接.然后在where子句中......

(@group_id is null or g.group_id = @group_id)
and (@address_id is null or a.address_id = @address_id)
Run Code Online (Sandbox Code Playgroud)

  • 这将给出正确的答案,但是在您加入的OR条件下,性能将变慢。 (2认同)