IIF在SQL的Where部分中选择

时间:2019-07-10 14:33:46

标签: 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,
    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)

我希望查看交易的用户级别为Admin(1),那么他/她可以查看所有数据。但是,如果级别为Standard(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)));

错误消息是:子查询返回了多个值。当子查询遵循=,!=,<,<=,>,> =或将子查询用作表达式时,不允许这样做。

2 个答案:

答案 0 :(得分:1)

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

顺便说一句,仅按样本数据来看,根本不需要为“管理员”使用过滤器。如果他们只能看到所有数据,那么您要做的就是:

WHERE @parLevelUser=1 OR idUserInput=@paridUserView

答案 1 :(得分:1)

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

SELECT * FROM tbTransactions 
WHERE idUserInput = IIF(
  @parLevelUser = 0,
  @paridUserView,
  idUserInput
);

如果@parLevelUser = 0(这意味着用户不是Admin,对吗?),则WHERE子句将为:

WHERE idUserInput = @paridUserView

,用户将只能看到他们的行。
如果@parLevelUser = 1(这意味着用户是Admin,对吗?),则 WHERE子句将为:

WHERE idUserInput = idUserInput 

,它为所有行返回true,因此管理员将看到所有行。
编辑。
您可以从tbUsers获取用户级别,而不是使用变量@parLevelUser

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