使用连接进行条件过滤

时间:2016-03-26 22:01:23

标签: sql-server tsql join

在具有单个参数的存储过程中,我的查询性质与以下内容类似:

SELECT
    ID,
    DepartmentID,
    FileName
FROM
    Document
-- conditional join from here
JOIN
    AllowedDepartmentList ON DepartmentID = AllowedDepartmentList.ID 
                          AND @IsAdmin = 'false'

参数为@IsAdmin,数据类型为bit。

我使用的两个表是Document表(参见上面查询中的结构),以及包含单个AllowedDepartmentList列的int

我使用此查询来过滤带有Document表的返回结果。我不使用WHERE DepartmentID IN()子句,因为AllowedDepartmentList可以长达600-700个项目(IN()太多,无法在可能的1M记录表中处理良好的性能) 所以我使用连接进行过滤,但是如果@IsAdmin参数是false,则只应执行过滤。就像之后的行 - 来自此处的条件连接注释甚至不存在。

我尝试了上面的查询,但它没有产生任何记录。我怀疑我使用了错误的联接类型,但是我被卡住了。

6 个答案:

答案 0 :(得分:3)

作为一般规则,将参数放入WHERE子句VS连接中。一个简单的解决方案是使用一个运行两个完全不同的查询的TVF或sproc。像这样的东西:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DiceGame
{
    class DiceClass
    {
        private static string nL = Environment.NewLine;
        string one = nL + " l ";
        string two = "l" + nL + nL + "  l";
        string three = "l l" + nL + nL + "l l";
        string four = "l l" + nL + nL + "l l";
        string five = "l l" + nL + " l " + nL + "l l";
        string six = "l l" + nL + "l l" + nL + "l l";
        private const int BOX = 6;
        private int firstDie;
        private int secondDie;
        Random randomNums = new Random();
        public DiceClass()
        {
            firstDie = 0;
            secondDie = 0;
        }

        public void RollEm()
        {
            firstDie = randomNums.Next(1, 7);
            secondDie = randomNums.Next(1, 7);
        }
        public bool BoxCars()
        {
            return firstDie == 6 && secondDie == 6;
        }

        public bool SnakeEyes()
        {
            return firstDie == 1 && secondDie == 1;
        }
        // is there an easier way to have this method work without all these if else statements??
        public void GetRoll(ref string first, ref string second)
        {
            if (firstDie == 1 && secondDie == 1)
            {
                first = one;
                second = one;
            }
            else if (firstDie == 1 && secondDie == 2)
            {
                first = one;
                second = two;
            }
            else if (firstDie == 1 && secondDie == 3)
            {
                first = one;
                second = three;
            }
            else if (firstDie == 1 && secondDie == 4)
            {
                first = one;
                second = four;
            }
            else if (firstDie == 1 && secondDie == 5)
            {
                first = one;
                second = five;
            }
            else if (firstDie == 1 && secondDie == 6)
            {
                first = one;
                second = six;
            }
            else if (firstDie == 2 && secondDie == 1)
            {
                first = two;
                second = one;
            }
            else if (firstDie == 2 && secondDie == 2)
            {
                first = two;
                second = two;
            }
            else if (firstDie == 2 && secondDie == 3)
            {
                first = two;
                second = three;
            }
            else if (firstDie == 2 && secondDie == 4)
            {
                first = two;
                second = four;
            }
            else if (firstDie == 2 && secondDie == 5)
            {
                first = two;
                second = five;
            }
            else if (firstDie == 2 && secondDie == 6)
            {
                first = two;
                second = six;
            }
            else if (firstDie == 3 && secondDie == 1)
            {
                first = three;
                second = one;
            }
            else if (firstDie == 3 && secondDie == 2)
            {
                first = three;
                second = two;
            }
            else if (firstDie == 3 && secondDie == 3)
            {
                first = three;
                second = three;
            }
            else if (firstDie == 3 && secondDie == 4)
            {
                first = three;
                second = four;
            }
            else if (firstDie == 3 && secondDie == 5)
            {
                first = three;
                second = five;
            }
            else if (firstDie == 3 && secondDie == 6)
            {
                first = three;
                second = six;
            }
            else if (firstDie == 4 && secondDie == 1)
            {
                first = four;
                second = one;
            }
            else if (firstDie == 4 && secondDie == 2)
            {
                first = four;
                second = two;
            }
            else if (firstDie == 4 && secondDie == 3)
            {
                first = four;
                second = three;
            }
            else if (firstDie == 4 && secondDie == 4)
            {
                first = four;
                second = four;
            }
            else if (firstDie == 4 && secondDie == 5)
            {
                first = four;
                second = five;
            }
            else if (firstDie == 4 && secondDie == 6)
            {
                first = four;
                second = six;
            }
            else if (firstDie == 5 && secondDie == 1)
            {
                first = five;
                second = one;
            }
            else if (firstDie == 5 && secondDie == 2)
            {
                first = five;
                second = two;
            }
            else if (firstDie == 5 && secondDie == 3)
            {
                first = five;
                second = three;
            }
            else if (firstDie == 5 && secondDie == 4)
            {
                first = five;
                second = four;
            }
            else if (firstDie == 5 && secondDie == 5)
            {
                first = five;
                second = five;
            }
            else if (firstDie == 5 && secondDie == 6)
            {
                first = five;
                second = six;
            }
            else if (firstDie == 6 && secondDie == 1)
            {
                first = six;
                second = one;
            }
            else if (firstDie == 6 && secondDie == 2)
            {
                first = six;
                second = two;
            }
            else if (firstDie == 6 && secondDie == 3)
            {
                first = six;
                second = three;
            }
            else if (firstDie == 6 && secondDie == 4)
            {
                first = six;
                second = four;
            }
            else if (firstDie == 6 && secondDie == 5)
            {
                first = six;
                second = five;
            }
            else
            {
                first = six;
                second = six;
            }
        }
    }
}

答案 1 :(得分:3)

您可以将左连接组合使用需要管理员权限的位置或连接上的匹配

SELECT
    ID,
    DepartmentID,
    FileName
FROM
    Document
-- conditional join from here
LEFT JOIN
    AllowedDepartmentList ON DepartmentID = AllowedDepartmentList.ID 
WHERE
    @IsAdmin = 'true' OR AllowedDepartmentList.ID IS NOT NULL

答案 2 :(得分:3)

您可以使用存在条件,如下所示:

SELECT
 ID,
 DepartmentID,
 FileName
FROM Document
WHERE exists(
 SELECT 1 from AllowedDepartmentList 
 WHERE DepartmentID = AllowedDepartmentList.ID) 
OR @IsAdmin = 'true'

答案 3 :(得分:3)

使用Dynamic query执行此操作的另一种方法。与JOIN/Exists选项

相比,这将具有良好的性能
DECLARE @sql     NVARCHAR(max)='',
        @IsAdmin BIT = 1

SET @sql = '
SELECT
    ID,
    DepartmentID,
    FileName
FROM
    Document D
    ' + CASE WHEN @IsAdmin = 'false' THEN ' where exists (select 1 from  AllowedDepartmentList AD where D.DepartmentID = AD.ID ) ' ELSE '' END

--PRINT @sql 

exec sp_executesql @sql 

@IsAdmin = 0

时的动态框架查询
SELECT ID,
       DepartmentID,
       FileName
FROM   Document D
WHERE  EXISTS (SELECT 1
               FROM   AllowedDepartmentList AD
               WHERE  D.DepartmentID = AD.ID) 

@IsAdmin = 0

时的动态框架查询
SELECT ID,
       DepartmentID,
       FileName
FROM   Document D

答案 4 :(得分:2)

以下查询可以帮助您

SELECT  ID
        ,DepartmentID
        ,FileName
FROM    Document
        LEFT JOIN   AllowedDepartmentList ON DepartmentID = AllowedDepartmentList.ID
WHERE   @isAdmin = 1
    OR  ( @isAdmin = 0 AND AllowedDepartmentList.ID IS NOT NULL)

答案 5 :(得分:1)

为admin添加一个类似-1的AllowedDepartmentList.ID 为@adminID

传递null或-1
ON isnull(@adminID, DepartmentID) = AllowedDepartmentList.ID

OR(或@IsAdmin =' true')效率不高,这也只返回1