Sql server IIF在SQL上的Where部分选择

Sql server IIF在SQL上的Where部分选择,sql-server,tsql,Sql Server,Tsql,假设这是我的数据 CREATE TABLE tbUsers ( idUser INT PRIMARY KEY, nameUser VARCHAR(20), levelUser BIT ); INSERT INTO tbUsers VALUES (1,'Cindy',1),(2,'Philip',0),(3,'Veron',0); CREATE TABLE tbTransactions ( idTransaction BIGINT PRIMARY KEY, dateTransa

假设这是我的数据

CREATE TABLE tbUsers (
idUser INT PRIMARY KEY,
nameUser VARCHAR(20),
levelUser BIT
);

INSERT INTO tbUsers VALUES (1,'Cindy',1),(2,'Philip',0),(3,'Veron',0);

CREATE TABLE tbTransactions (
    idTransaction BIGINT PRIMARY KEY,
    dateTransaction DATE,
    idUserInput INT
);

INSERT INTO tbTransactions VALUES (1,'2019-07-01',1),(2,'2019-07-05',1),(3,'2019-07-05',3);
级别用户有2个:管理员(1)和标准(0)


如果查看事务的用户是级别管理员(1),我希望他/她可以查看所有数据。但如果级别标准为(0),则他/她只能查看他/她的数据

如果我使用If语句,我就能达到我的目标。这是IF代码:

DECLARE @parLevelUser BIT = 1;
DECLARE @parIdUserView INT = 3;

IF(@parLevelUser=1)
    SELECT * FROM tbTransactions WHERE idUserInput IN (SELECT idUser FROM tbUsers)
ELSE
    SELECT * FROM tbTransactions WHERE idUserInput IN (SELECT @paridUserView)
如何在IIF报表中写入?我写了这段代码,但显示错误

DECLARE @parLevelUser BIT = 1;
DECLARE @parIdUserView INT = 3;
SELECT * FROM tbTransactions WHERE idUserInput IN (IIF(@parLevelUser=1,(SELECT idUser FROM tbUsers),(SELECT @paridUserView)));

错误消息为:子查询返回的值超过1。当子查询在=、!=、=或者,当子查询用作表达式时。

您不能使用IIF表达式执行此操作。您的IF代码是执行此操作的正确方法

顺便说一下,仅根据示例数据,根本不需要对“管理员”使用过滤器。如果他们可以简单地看到所有数据,那么您所要做的就是:

WHERE @parLevelUser=1 OR idUserInput=@paridUserView

你不能用IIF表达式这样做。您的IF代码是执行此操作的正确方法

顺便说一下,仅根据示例数据,根本不需要对“管理员”使用过滤器。如果他们可以简单地看到所有数据,那么您所要做的就是:

WHERE @parLevelUser=1 OR idUserInput=@paridUserView

如果我理解了变量的含义,您可以这样做:

SELECT * FROM tbTransactions 
WHERE idUserInput = IIF(
  @parLevelUser = 0,
  @paridUserView,
  idUserInput
);
如果
@parLevelUser=0
(这意味着该用户不是管理员,对吗?),则
WHERE
子句将是:

WHERE idUserInput = @paridUserView
WHERE idUserInput = idUserInput 
用户将只看到他们的行。
如果
@parLevelUser=1
(这意味着用户是管理员,对吗?)
其中
条款为:

WHERE idUserInput = @paridUserView
WHERE idUserInput = idUserInput 
它为所有行返回
true
,以便管理员查看所有行。
编辑。
您可以从
tbUsers
获取用户级别,而不是使用变量
@parLevelUser

SELECT * FROM tbTransactions 
WHERE idUserInput = IIF(
  (select levelUser from tbUsers where idUser = @paridUserView) = 0,
  @paridUserView,
  idUserInput
);

如果我理解了变量的含义,您可以这样做:

SELECT * FROM tbTransactions 
WHERE idUserInput = IIF(
  @parLevelUser = 0,
  @paridUserView,
  idUserInput
);
如果
@parLevelUser=0
(这意味着该用户不是管理员,对吗?),则
WHERE
子句将是:

WHERE idUserInput = @paridUserView
WHERE idUserInput = idUserInput 
用户将只看到他们的行。
如果
@parLevelUser=1
(这意味着用户是管理员,对吗?)
其中
条款为:

WHERE idUserInput = @paridUserView
WHERE idUserInput = idUserInput 
它为所有行返回
true
,以便管理员查看所有行。
编辑。
您可以从
tbUsers
获取用户级别,而不是使用变量
@parLevelUser

SELECT * FROM tbTransactions 
WHERE idUserInput = IIF(
  (select levelUser from tbUsers where idUser = @paridUserView) = 0,
  @paridUserView,
  idUserInput
);

你能解释一下吗?我想如果查看事务的用户是级别管理员(1),那么他/她可以查看所有数据。但是如果级别标准(0),他/她只能查看他/她的数据。代码就是这样做的。如果将0或1传递给@parLevelUser并传递用户的idin@paridUserView.Can你解释一下吗?我想如果查看事务的用户是级别管理员(1),那么他/她可以查看所有数据。但是如果级别标准(0),他/她只能查看他/她的数据。代码就是这样做的。如果将0或1传递给@parLevelUser并传递用户的idin@paridUserView.A单个查询永远不会像使用
IF
的两个单独查询那样提供优化的执行计划。一般来说,即使在可能的情况下,您也不希望将尽可能多的条件填充到单个查询中作为目标;优化器根本不喜欢这样。小心优化查询长度和“代码重用”。顺便说一句,SQL Server的最新版本提供了一个功能,引擎可以根据条件自动筛选表(例如,
SESSION\u CONTEXT
)。对于自定义应用程序检查(更灵活)来说,这并不总是一个合适的替代方案,但在需要时可以节省大量代码。一个查询永远不会像使用
IF
的两个单独查询那样提供优化的执行计划。一般来说,即使在可能的情况下,您也不希望将尽可能多的条件填充到单个查询中作为目标;优化器根本不喜欢这样。小心优化查询长度和“代码重用”。顺便说一句,SQL Server的最新版本提供了一个功能,引擎可以根据条件自动筛选表(例如,
SESSION\u CONTEXT
)。对于自定义应用程序检查(更灵活)来说,这并不总是一个合适的替代方案,但在需要时可以节省大量代码。