仅当临时表具有值时才使用内部联接

时间:2018-10-18 00:38:35

标签: sql sql-server tsql

我有动态查询,首先在其中创建一个临时表,然后填充它:

CREATE TABLE [#SearchKeys] ([DesignKey] INT);

INSERT INTO [#SearchKeys]
    SELECT
        [pd].[DesignKey]
    FROM 
        [Project] AS [p]
    ....

一旦有了数据,我就将其用于动态查询的INNER JOIN部分,例如:

INNER JOIN 
    (SELECT DesignKey FROM #SearchKeys) AS [S] ON [S].[DesignKey] = [PD].[DesignKey]

问题是我只想在临时表具有值的情况下添加此INNER JOIN,否则就不要执行它。我该如何实现?问候

2 个答案:

答案 0 :(得分:1)

我没有从您的问题中看到动态查询。但是我在这里给你伪代码

--Check for If Data Exist in #SearchKeys
IF Exists (SELECT 1 FROM #SearchKeys)--Condition to check value available in temp table
BEGIN
   --without INNER JOIN Query
END
ELSE
BEGIN
   -- with INNER JOIN Query
   INNER JOIN (SELECT DesignKey FROM #SearchKeys) AS [S] ON [S].[DesignKey] = [PD].[DesignKey]
END

答案 1 :(得分:1)

我的建议是完全内联的:

DECLARE @mockupTable TABLE(ID INT IDENTITY,Content INT);
INSERT INTO @mockupTable VALUES(10),(20),(30);

DECLARE @SearchKeys TABLE(DesignKey INT);
--Keep it empty in the first run, then decomment the insert to see the difference
--INSERT INTO @SearchKeys VALUES(20)

SELECT *
FROM @mockupTable t
LEFT JOIN @SearchKeys k ON t.Content=k.DesignKey
WHERE ((SELECT COUNT(*) FROM @SearchKeys)=0 OR DesignKey IS NOT NULL); 

在任何情况下,LEFT JOIN将返回所有行。 WHERE将决定SearchKey表中是否有过滤器。在这种情况下,仅返回具有相应键的行。

提示:如果需要,您可以使用IS NULL而不是IS NOT NULL轻松地将键变成反模式。在这种情况下,您将引入一个变量并使用类似OR ((@antipattern=0 AND ...) OR (@antipattern=1 AND ...))

Developer_29的其他答案将得到更好的优化,从而更快。但是在许多情况下,我们不希望使用“多语句”方法