如果连接表不包含任何行,则返回所有行,否则仅返回匹配的行

时间:2015-08-18 16:44:28

标签: sql-server

数据库结构

CREATE TABLE SalesOrder
(
    ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    Reference NVARCHAR(50) NOT NULL DEFAULT '',
    CustomerID INT NOT NULL DEFAULT 0
);
CREATE NONCLUSTERED INDEX IX_SalesOrder_CustomerID ON SalesOrder (CustomerID);

CREATE TABLE Customer
(
    ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    Name NVARCHAR(50) NOT NULL DEFAULT ''
);

示例:SQL Fiddle

表值变量@SelectedCustomers可以为空或包含用户选择的客户ID列表。
此查询返回所选客户的订单,如果所选列表为空,则不返回任何内容

SELECT so.ID
, so.Reference
, c.Name AS CustomerName
FROM SalesOrder so
INNER JOIN Customer c ON c.ID = so.CustomerID
WHERE so.CustomerID IN (SELECT ID FROM @SelectedCustomers)

但如果变量为空,我需要返回所有行 我尝试了OR关键字,但这种方法不易索引,查询变得非常慢。

目前,我在应用程序的代码(.NET)中生成查询 如果列表包含一些值,则
WHERE so.CustomerID IN (SELECT ID FROM @SelectedCustomers)子句添加到查询

问题:是否存在其他方式以更有效的方式获得所需的结果?

3 个答案:

答案 0 :(得分:1)

不一样的 如果@SelectedCustomers具有值但不匹配

,则会返回
SELECT so.ID
     , so.Reference
     , c.Name AS CustomerName
FROM SalesOrder so
INNER JOIN Customer c ON c.ID = so.CustomerID 
LEFT  JOIN @SelectedCustomers s on so.CustomerID = s.ID 
WHERE s.ID is null  

联盟可能会起作用

SELECT so.ID
     , so.Reference
     , c.Name AS CustomerName
 FROM SalesOrder so
JOIN Customer c ON c.ID = so.CustomerID 
JOIN @SelectedCustomers on so.CustomerID = @SelectedCustomers.ID 
union 
SELECT so.ID
     , so.Reference
     , c.Name AS CustomerName
FROM SalesOrder so
JOIN Customer c ON c.ID = so.CustomerID 
where (select top 1 ID from @SelectedCustomers) is null

或者我知道这听起来很疯狂,但如果@SelectedCustomers中没有行,则插入所有不同的ID。你离开了OR。

答案 1 :(得分:0)

添加到where语句的where end:

或@selectedcustomer为空

答案 2 :(得分:0)

不确定,但这可能有效:

{{1}}