SQL子查询使用IN Statment与coalesce

时间:2015-11-02 16:41:13

标签: sql subquery coalesce sql-in

我有以下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临时表。如果没有用户输入,那么表格将包含nothin

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

  

子查询返回的值超过1。这是不允许的   子查询跟随=,!=,&lt;,&lt; =,&gt;,&gt; =或当子查询用作   表达。

我不知道为什么会这样。任何可以帮我解决这个问题的想法?

4 个答案:

答案 0 :(得分:0)

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

SELECT DISTINCT PrivId FROM cte_getAll

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

如果我正确理解了您的问题,那么您有一个表格变量,其中包含您想要选择的值,但如果他们在表格中没有任何值,则您不希望在所有

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

答案 3 :(得分: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))