Sql 进行双重目的查询,还是两个单独的查询? 这是一个虚构的例子,但是考虑一个场景,员工有工作地点,员工也有工作地点的管理者: create table WorkingLocation ( ID int not null primary key identity(1,1), Name varchar(50) ) create table Employee ( ID int not null primary key identity(1,1), Name varchar(50), WorkingLocationID int null, ManagerID int null, constraint FK_Employee_WorkingLocation foreign key (WorkingLocationID) references WorkingLocation (ID), constraint FK_Employee_Manager foreign key (ManagerID) references Employee (ID) ) 现在考虑一个业务规则,它要求雇员的代码>工作位置< /代码>,但是如果他没有,则将满足他的经理的代码代码>。此时,您有两个选择:

Sql 进行双重目的查询,还是两个单独的查询? 这是一个虚构的例子,但是考虑一个场景,员工有工作地点,员工也有工作地点的管理者: create table WorkingLocation ( ID int not null primary key identity(1,1), Name varchar(50) ) create table Employee ( ID int not null primary key identity(1,1), Name varchar(50), WorkingLocationID int null, ManagerID int null, constraint FK_Employee_WorkingLocation foreign key (WorkingLocationID) references WorkingLocation (ID), constraint FK_Employee_Manager foreign key (ManagerID) references Employee (ID) ) 现在考虑一个业务规则,它要求雇员的代码>工作位置< /代码>,但是如果他没有,则将满足他的经理的代码代码>。此时,您有两个选择:,sql,performance,Sql,Performance,1:有一个同时获取这两个数据的查询,并让业务规则决定使用哪一个: select e.*, emp_location.*, mgr_location.* from Employee e left join WorkingLocation emp_location on e.WorkingLocationID = emp_location.ID left join Employee mgr on e.ManagerID = mgr.ID left j

1:有一个同时获取这两个数据的查询,并让业务规则决定使用哪一个:

select 
    e.*,
    emp_location.*,
    mgr_location.*
from Employee e
    left join WorkingLocation emp_location on e.WorkingLocationID = emp_location.ID
    left join Employee mgr on e.ManagerID = mgr.ID
    left join WorkingLocation mgr_location on mgr.WorkingLocationID = mgr_location.ID
where e.ID = @id
2:如果员工没有
工作地点设置,则分别调用数据库以检索经理的详细信息。


你更喜欢哪一个?为什么?

我会非常明确地选择选项1

有一个同时得到和让的查询 商业规则决定了该选择哪一个 使用


我总是说避免多次调用数据库,除非您返回的数据量不合理和/或查询需要很长时间。

尝试这两种方法,看看哪种方法在您的环境中性能更好,保留在以后发生变化时切换方法的选项


我认为您不必选择一个解决方案并永远坚持下去。

还有另一个选项-使用COALESCE或使用null coalescing运算符在t-SQL查询中指定规则??在您的代码中(也适用于LinqToSQL)


任何一个都只需要一个调用数据库,所以选项1是1。

< P>如果你不关心返回的位置,那么,正如迈克所说的,你可以考虑合并雇员和管理者的位置。然而,这确实将业务逻辑移动到您可以考虑的数据访问层中,因此,取决于您的严格程度,您可能更喜欢在别处强制执行这样的规则。在这种情况下,我可能会投票选择选项1。

编辑:如果必须选择1,那么:

select e.*, wl.*
from Employee e 
inner join WorkingLocation wl
on e.WorkingLocationID = wl.ID
union
select e.*, wl.*
from Employee e 
inner join Employee m
on m.ID = e.ManagerID 
inner join WorkingLocation wl
on m.WorkingLocationID = wl.ID
where not exists (select 1
   from WorkingLocation wl
   on wl.ID = e.WorkingLocationID)

我知道您的模式是人为设计的,但正如Mike所建议的,ISNULL或COALESCE语句将不起作用,因为WorkingLocationID不可为Null,因此员工必须有一个位置。但是,如果有一个默认位置指示员工没有位置,比如使用值0,那么使用CASE语句就可以了。请注意,对于所需的每个WorkingLocation字段,都需要一个CASE语句。因此,查询变得类似于:

   SELECT e.*
        , CASE
              WHEN emp_location.WorkingLocationID = 0
              THEN mgr_location.ID
              ELSE emp_location.ID
          END AS Location
        , CASE
              WHEN emp_location.WorkingLocationID = 0
              THEN mgr_location.Name
              ELSE emp_location.Name
          END AS Name
     FROM Employee e
LEFT JOIN WorkingLocation emp_location
       ON e.WorkingLocationID = emp_location.ID
LEFT JOIN Employee mgr
       ON e.ManagerID = mgr.ID
LEFT JOIN WorkingLocation mgr_location
       ON mgr.WorkingLocationID = mgr_location.ID
    WHERE e.ID = @id

我始终支持对数据库服务器的总体影响最小的选项。我们只能有一个数据库服务器,但我们可以有许多应用程序服务器。很好地发现WorkingLocationID不可为null,我假设它可以为null,这与问题一致。如果没有位置,我将始终使用
null
,而不是
0
或任何其他幻数。很好,我已经相应地更新了问题。