SQL 使用带合并的 IN 语句的子查询

SQL Subquery using IN Statment with coalesce

我有以下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 temp table。如果没有用户输入,那么 table 将不包含任何内容

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

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

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

由于您要在该语句之前填充临时 table @selectedPriv,只需在此处添加一个 else - 如果输入为空,则具有 @selectedPriv =

SELECT DISTINCT PrivId FROM cte_getAll

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

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

AND (((select count(*) from @selectedPriv) = 0)
    OR ((select count(*) from @selectedPriv) != 0 AND allUsers.[PrivId] IN (SELECT privId from @selectedPriv)))

如果我对你的问题的理解正确,你有一个 table 变量,它具有你想要 select 来自的值,但如果它们在 table, 你根本不需要限制。

您收到错误的原因是 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)
    )
 )

合并工作正常,但您可以改用 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))