Sql 基于另一个表的可选Where子句

Sql 基于另一个表的可选Where子句,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个存储过程,其中整数表作为参数传递。我试图找到一种合理的方式来写“给我所有的记录,但是如果参数表中有值,那么将我的结果限制在这些值上” 下面查询中的两种方法都可以工作,但是当我在现实世界的proc中使用这两种方法时(有大量的连接和apply子句以及大量的数据),即使变量表中的行数限制为1或2条记录,也会比我希望的慢很多 有更好的方法吗 -- Apprroach1 - Weird WHERE clause IF OBJECT_ID('tempdb.dbo.#list') IS NOT NUL

我有一个存储过程,其中整数表作为参数传递。我试图找到一种合理的方式来写“给我所有的记录,但是如果参数表中有值,那么将我的结果限制在这些值上”

下面查询中的两种方法都可以工作,但是当我在现实世界的proc中使用这两种方法时(有大量的连接和apply子句以及大量的数据),即使变量表中的行数限制为1或2条记录,也会比我希望的慢很多

有更好的方法吗

-- Apprroach1 - Weird WHERE clause
IF OBJECT_ID('tempdb.dbo.#list') IS NOT NULL  DROP TABLE #list

create table #list(Id int)
insert into #list(id) values (726), (712), (725)

declare @listCount int
select @listCount = count(*) from #list

select * from SalesLT.Product p
where 1 = 1
AND 
    (
        @listCount > 0 AND p.ProductID in (select Id from #list)
        OR
        @listCount = 0
    )


通常,避免在联接中(ON子句)出现
情况,因为这会降低查询的性能

使用
左连接方法,如下所示:

select * from SalesLT.Product p
Left join #list l on l.Id = p.ProductID 
Where ( (@listCount > 0 and l.id is not null) 
        or @listCount = 0)

通常,避免在联接中(
ON
子句)出现
情况,因为这会降低查询的性能

使用
左连接方法,如下所示:

select * from SalesLT.Product p
Left join #list l on l.Id = p.ProductID 
Where ( (@listCount > 0 and l.id is not null) 
        or @listCount = 0)
试试这个

如果@listCount>0
开始
挑选
* 
来自SalesLT.Product p
------------------------
内部联接#列表l打开
------------------------
l、 Id=p.ProductID
------------------------
结束
--如果@listCount=0,我假设您希望输出所有内容
如果@listCount=0,则为ELSE
开始
挑选
* 
来自SalesLT.Product p
结束
如果有一组使用该表输出的联接,则可以存储输出并在实际联接/查询中使用它

例如:

IF @listCount > 0
BEGIN
   SELECT 
      * 
   INTO #TempSalesTbl 
   FROM SalesLT.Product p
   ------------------------
   INNER JOIN #list l ON 
   ------------------------
      l.Id = p.ProductID
   ------------------------
END
-- In your query
SELECT
  *
FROM Table A
INNER JOIN #TempSalesTbl  ON
   ... 
试试这个

如果@listCount>0
开始
挑选
* 
来自SalesLT.Product p
------------------------
内部联接#列表l打开
------------------------
l、 Id=p.ProductID
------------------------
结束
--如果@listCount=0,我假设您希望输出所有内容
如果@listCount=0,则为ELSE
开始
挑选
* 
来自SalesLT.Product p
结束
如果有一组使用该表输出的联接,则可以存储输出并在实际联接/查询中使用它

例如:

IF @listCount > 0
BEGIN
   SELECT 
      * 
   INTO #TempSalesTbl 
   FROM SalesLT.Product p
   ------------------------
   INNER JOIN #list l ON 
   ------------------------
      l.Id = p.ProductID
   ------------------------
END
-- In your query
SELECT
  *
FROM Table A
INNER JOIN #TempSalesTbl  ON
   ... 

当检查是否存在一行或多行时,使用该行比获取精确值然后仅检查其是否大于零更有效。当检查是否存在一行或多行时,使用该行比获取精确值然后仅检查其是否大于零更有效。这就行了,但是需要我复制比示例长得多的查询。这是可行的,但是需要我复制比示例长得多的查询。