检查IF与WHERE子句中的条件

时间:2014-07-25 06:45:43

标签: sql sql-server-2008 tsql

我遇到了问题,我有2个问题的解决方案。我必须编写一个程序,它将返回属于所需类别的行。所需的类别将作为布尔(或位)值传递。第一个解决方案是: -

DECLARE @IsRowType1Req bit;
DECLARE @IsRowType2Req bit;

DECLARE @tbl1 table (ID int, RowType varchar(50));

DECLARE @tmpTbl table (ID int, RowType varchar(50));

IF @IsRowType1Req = 1
    INSERT INTO
        @tmpTbl
    SELECT 
        * 
    FROM 
        @tbl1 
    WHERE 
        RowType = 'RowType1';

IF @IsRowType2Req = 1
    INSERT INTO
        @tmpTbl
    SELECT 
        * 
    FROM 
        @tbl1 
    WHERE 
        RowType = 'RowType2';

SELECT * FROM @tmpTbl;

现在,此解决方案使用IF子句仅选择所需的行类型。另一个是: -

DECLARE @IsRowType1Req bit;
DECLARE @IsRowType2Req bit;

DECLARE @tbl1 table (ID int, RowType varchar(50));

SELECT 
    * 
FROM 
    @tbl1 
WHERE 
    RowType = 'RowType1' AND 
    @IsRowType1Req = 1

UNION

SELECT 
    * 
FROM 
    @tbl1 
WHERE 
    RowType = 'RowType2' AND 
    @IsRowType2Req = 1

此解决方案利用WHERE子句来限制不需要的行类型。任何人都可以告诉我哪一个更快,为什么?

3 个答案:

答案 0 :(得分:2)

根据您提供的信息,似乎无需使用UNION IF

SELECT *
FROM @tbl1
WHERE
  (RowType = 'RowType2' AND @IsRowType2Req = 1)
  OR (RowType = 'RowType1' AND @IsRowType1Req = 1);

答案 1 :(得分:1)

答案可能取决于表格的大小以及返回的每个子集的大小。

IF解决方案必须将行插入另一个表中,这并不便宜。另一方面,WHERE解决方案使用UNION,它意味着排序以删除重复的条目。如果你用UNION ALL替换UNION(你可以安全地做,因为你的两个子集永远不会有重复),WHERE解决方案将成为两个人中较好的一个。

但是,由于@tbl1中的行不能超过一种类型,因此您可以采用不同的方式解决问题。您可以将@tbl1与包含0,1或2行的动态构建表进行匹配,具体取决于@IsRowType1Req@IsRowType2Req的值。您可以像这样构建该表:

SELECT 'RowType1' WHERE @IsRowType1Req = 1
UNION ALL
SELECT 'RowType2' WHERE @IsRowType2Req = 1

然后将其加入@tbl1

SELECT 
    * 
FROM 
    @tbl1 AS t
INNER JOIN
    (
    SELECT 'RowType1' WHERE @IsRowType1Req = 1
    UNION ALL
    SELECT 'RowType2' WHERE @IsRowType2Req = 1
    ) AS f (RowType)
ON
    t.RowType = f.RowType
;

在某种程度上,这可能意味着WHERE仍然“获胜”,但您可以在不使用WHERE的情况下重写虚拟表:

SELECT CASE @IsRowType1Req WHEN 1 THEN 'RowType1' END
UNION ALL
SELECT CASE @IsRowType2Req WHEN 1 THEN 'RowType2' END

或者像这样,使用SQL Server 2008中引入的VALUES构造函数:

VALUES
    (CASE @IsRowType1Req WHEN 1 THEN 'RowType1' END),
    (CASE @IsRowType2Req WHEN 1 THEN 'RowType2' END)

这样,表总是包含2行,每行包含请求的类型或NULL。与该表连接的结果仍然相同,并且与您期望的结果相符。

答案 2 :(得分:0)

在这种情况下,我会选择IF,但这只是因为你使用的是UNION子句,这意味着你要运行两个单一查询然后合并结果。

如果使用UNION,SQL Server需要确保组合结果集不包含任何重复行,因此需要运行两个查询,然后比较结果集以检查重合。

您可以在此处详细解释http://webbtechsolutions.com/2009/08/06/the-effects-union-in-a-sql-query/