0

我有以下 SELECT 语句

SELECT
       UserID
      ,UserName
      ,TradingParty
      ,Email
      ,[PrivDesc]
      ,LastLogin
      ,IsApproved

FROM
    cte_getAll allUsers
 WHERE
      allUsers.TradingParty                                            = COALESCE(@TradingParty, allUsers.TradingParty)
    AND allUsers.Username                                      = COALESCE(@Username, allUsers.Username) 
    AND allUsers.Email                                       = COALESCE(@EmailAddress, allUsers.Email)
    AND DATEADD(dd, DATEDIFF(dd, 0, allUsers.[LastLogin]), 0)   >= COALESCE(@FromDate, DATEADD(dd, DATEDIFF(dd, 0, allUsers.[LastLogin]), 0)) 
    AND DATEADD(dd, DATEDIFF(dd, 0, allUsers.[LastLogin]), 0)   <= COALESCE(  @ToDate, DATEADD(dd, DATEDIFF(dd, 0, allUsers.[LastLogin]), 0))
    AND allUsers.IsApproved                                   = COALESCE(@AccountActive, allUsers.IsApproved)
      AND allUsers.[PrivId]                                        -- IN (SELECT privId from @selectedPriv)
                                                                      IN (COALESCE((SELECT PrivID FROM @selectedPriv), allUsers.[PrivId]))

编辑 在此声明之前,我正在根据用户输入填充 @selectedPriv 临时表。如果没有用户输入,则该表将不包含任何内容

在最后的 AND 语句中,我试图找到 privId 等于用户输入的 privs 列表的所有数据。因此,例如,用户输入存储到临时表中的 1、2、3、4、5、6,从这里我需要从我的原始表中找到与这些 priv 关联的所有行。这是我的问题,如果我使用注释的 IN 语句,它可以工作,但是由于允许用户传入 NULL,我需要在 COALESCE 中使用它,但是当我这样做时,我会收到消息

子查询返回超过 1 个值。当子查询跟随 =、!=、<、<=、>、>= 或子查询用作表达式时,这是不允许的。

我不知道为什么会这样。有什么想法可以帮助我解决这个问题吗?

4

4 回答 4

1

如果我正确理解您的问题,则您有一个表变量,其中包含您要从中选择的值,但如果它们在表中没有任何值,则您根本不需要限制。

您收到错误的原因是COALESCE()只希望转换一个值,但您的查询返回多个。

这可能是您正在寻找的:

 AND 
 (
    NOT EXISTS (SELECT * FROM @selectedPriv WHERE PrivID IS NOT NULL)
    OR
    (
            EXISTS (SELECT * FROM @selectedPriv WHERE PrivID IS NOT NULL) 
        AND allUsers.[PrivId] IN (SELECT PrivID FROM @selectedPriv)
    )
 )
于 2015-11-02T16:51:14.317 回答
0

coalesce 工作正常,但您可以使用 OR,这可能会帮助您完成最后一个 AND。

SELECT
    UserID,
    UserName,
    TradingParty,
    Email,
    [PrivDesc],
    LastLogin,
    IsApproved
FROM
    cte_getAll allUsers
WHERE
    allUsers.TradingParty = COALESCE(@TradingParty,allUsers.TradingParty)
    AND (@Username IS NULL OR allUsers.Username = @Username)

    AND (@EmailAddress IS NULL OR allUsers.Email = @EmailAddress)
    AND (@FromDate IS NULL OR DATEADD(dd,DATEDIFF(dd,0,allUsers.[LastLogin]),0) >= @FromDate)
    AND (@ToDate IS NULL OR DATEADD(dd,DATEDIFF(dd,0,allUsers.[LastLogin]),0) <= @ToDate)
    AND (@AccountActive IS NULL OR allUsers.IsApproved = @AccountActive)
    AND (@PrivIDS IS NULL OR allUsers.[PrivId] IN (SELECT PrivID FROM @selectedPriv))
于 2015-11-02T16:54:42.160 回答
0

由于您在此语句之前填充了临时表 @selectedPriv ,因此只需在此处添加一个 else ——如果输入为空,则有 @selectedPriv =

SELECT DISTINCT PrivId FROM cte_getAll

这应该比检查 @selectedPriv 中的 count(*) 的更复杂的 where 语句更快,这是另一种方法。

于 2015-11-02T16:49:37.487 回答
0

COALESCE 的第一个参数只能取一个值,这就是为什么当您从该查询中获得多个值时它会抱怨。您可以使用一些 AND 和 OR 将该部分切换为一些不同的东西。(注意:未经测试,但至少应该接近。)

AND (((select count(*) from @selectedPriv) = 0)
    OR ((select count(*) from @selectedPriv) != 0 AND allUsers.[PrivId] IN (SELECT privId from @selectedPriv)))
于 2015-11-02T16:50:09.503 回答