在具有单个参数的存储过程中,我的查询性质与以下内容类似:
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
,则只应执行过滤。就像之后的行 - 来自此处的条件连接注释甚至不存在。
我尝试了上面的查询,但它没有产生任何记录。我怀疑我使用了错误的联接类型,但是我被卡住了。
答案 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或-1ON isnull(@adminID, DepartmentID) = AllowedDepartmentList.ID
OR(或@IsAdmin =' true')效率不高,这也只返回1