即使使用IN运算符,子查询也返回了1个以上的值

时间:2015-10-06 15:09:14

标签: sql sql-server

我的查询非常大,但出于理解目的,我粘贴在这里

SELECT    DISTINCT 
                  ISNULL(CD.InteractionID,'')       AS  InteractionID
                , ISNULL(CD.CaseID,'')                  AS CaseID
                , ISNULL(CD.AnalysisMonth,'')  + '-' + CAST( AnalysisYear AS VARCHAR(10)) AS MonYr
                , ISNULL(ServiceType,'')            AS ServiceType
                , ISNULL(ServiceSubType,'')         AS ServiceSubType  
                , ISNULL(SM.SourceName,'')          AS SourceName
                , ISNULL(UserComment,'')            AS UserComment
                , ISNULL(Final,'')                  AS Final
                , ISNULL(SYSM.SystemName,'')        AS SystemName
                , ISNULL(SSM.SubSystem,'')          AS SubSystem
                , ISNULL(CM.CategoryDesc,'')        AS CategoryDesc
                , ISNULL(ITCM.ITCommentDesc,'')     AS ITCommentDesc
                , ISNULL(Casedetails,'')            AS Casedetails
                , ISNULL(TempRCA,'')                AS TempRCA
                , ISNULL(FinalRCA,'')               AS FinalRCA
                , ISNULL(SysOwnerComments  ,'')     AS SysOwnerComments 
             FROM     
                [IT_COMPLAINTS].[ITC_Casedetails]       CD      WITH (NOLOCK) 
            INNER JOIN  [IT_COMPLAINTS].ITC_SourceMaster        SM      WITH (NOLOCK) ON  CD.SourceID   =SM.SourceID    
            LEFT JOIN   [IT_COMPLAINTS].[ITC_SystemMaster]      SYSM    WITH (NOLOCK) ON  CD.SystemID   =SYSM.SystemID    
            LEFT JOIN   [IT_COMPLAINTS].[ITC_SubSystemMaster]   SSM     WITH (NOLOCK) ON  CD.SubSystemID=SSM.SubSystemID AND CD.SystemID=SSM.SystemID    
            LEFT JOIN   [IT_COMPLAINTS].[ITC_CategoryMaster]    CM      WITH (NOLOCK) ON  CD.CategoryID =CM.CategoryID    
            LEFT JOIN   [IT_COMPLAINTS].[ITC_ITCommentMaster]   ITCM    WITH (NOLOCK) ON  CD.ITCommentID=ITCM.ITCommentID   
            INNER JOIN  [IT_COMPLAINTS].[ITC_SystemUserMapping] MAP WITH (NOLOCK) ON SSM.SubSystemID = MAP.SubSystemID
           WHERE 
                (IsNull(@InteractionNo,'')=''   OR ISNULL(CD.InteractionID,'')=@InteractionNo) 
            AND (ISNULL(@Mon,'' )=''            OR ISNULL(CD.AnalysisMonth,'')=@Mon) 
            AND (IsNull(@Year,0)=0              OR ISNULL(CD.AnalysisYear,'')=@Year) 

--    
            AND CD.SystemID IN 
                 ( CASE WHEN @SystemID = 0 THEN 
                         (SELECT SystemID 
                          FROM IT_COMPLAINTS.ITC_SystemUserMapping 
                          WHERE UserID = @UserID AND IsActive = 1) 
                   ELSE @SystemID END)

            AND CD.SubSystemID IN 
                 (CASE WHEN @SystemID = 0 THEN 
                       (SELECT SubSystemID 
                        FROM IT_COMPLAINTS.ITC_SystemUserMapping 
                        WHERE UserID = @UserID AND IsActive = 1) 
                  WHEN @SystemID > 0 AND @SubSystemID = 0 THEN 
                       (SELECT SubSystemID 
                        FROM IT_COMPLAINTS.ITC_SystemUserMapping 
                        WHERE UserID = @UserID AND 
                              IsActive = 1 AND 
                              SystemID = @SystemID)
                  ELSE @SubSystemID END)
--
            AND (ISNULL(@CategoryID,'')=''      OR ISNULL(CD.CategoryID,'')=@CategoryID) 
            AND (ISNULL(@ITCommentID,0)=0       OR ISNULL(CD.ITCommentID,'')=@ITCommentID)

然而,当我运行它时,它给了我一个错误

  

子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。

问题出在以下部分

AND CD.SystemID IN 
    ( CASE WHEN @SystemID = 0 THEN 
      (SELECT SystemID 
       FROM IT_COMPLAINTS.ITC_SystemUserMapping 
       WHERE UserID = @UserID AND 
         IsActive = 1) ELSE @SystemID END) 
AND CD.SubSystemID IN 
          (CASE WHEN @SystemID = 0 THEN 
            (SELECT SubSystemID 
             FROM IT_COMPLAINTS.ITC_SystemUserMapping 
             WHERE UserID = @UserID AND 
               IsActive = 1) 
          WHEN @SystemID > 0 AND @SubSystemID = 0 THEN 
           (SELECT SubSystemID 
            FROM IT_COMPLAINTS.ITC_SystemUserMapping 
            WHERE UserID = @UserID AND 
              IsActive = 1 AND 
              SystemID = @SystemID)
          ELSE @SubSystemID END)

当我对此进行评论时,我的查询有效,但是IN SubqueryCase的问题是什么?

4 个答案:

答案 0 :(得分:2)

像@zedfoxus评论的那样,问题在于这一部分:

...那么(从IT_COMPLAINTS.ITC_SystemUserMapping中选择SubSystemID

因为如果返回的值超过1,则无法放置该值。您应该用以下内容替换它:

CD.SubSystemID IN (
    SELECT 
      SubSystemID 
    FROM 
      IT_COMPLAINTS.ITC_SystemUserMapping 
    WHERE 
      UserID = @UserID AND 
      IsActive = 1 AND 
      (
        @SystemID = 0 or 
        (SystemID = @SystemID and @SubSystemID = 0)
      ) 
    union all 
    select @SybSystemID where @SystemID > 0 and @SubSystemID > 0
    )

这可能需要进行小幅调整,但您应该明白这一点。

除此之外,您可能希望研究使用“if exists”类型的结构。编写通常要简单得多,并且表现也更好。

答案 1 :(得分:0)

在以下SubSystemID子句中,您似乎会为AND SystemID = @SystemID而不是WHERE返回多个值:

        WHEN @SystemID = 0
            THEN (
                    SELECT SubSystemID
                    FROM IT_COMPLAINTS.ITC_SystemUserMapping
                    WHERE UserID = @UserID
                        AND IsActive = 1
                    )

答案 2 :(得分:0)

而不是:

            FROM     
                [IT_COMPLAINTS].[ITC_Casedetails]  CD  WITH (NOLOCK) 
...    
AND CD.SystemID IN 
    ( CASE WHEN @SystemID = 0 THEN 
      (SELECT SystemID 
       FROM IT_COMPLAINTS.ITC_SystemUserMapping 
       WHERE ...) ELSE @SystemID END) 
AND CD.SubSystemID IN 
          (CASE WHEN @SystemID = 0 THEN 
            (SELECT SubSystemID 
             FROM IT_COMPLAINTS.ITC_SystemUserMapping 
             WHERE ...) 
          WHEN @SystemID > 0 AND @SubSystemID = 0 THEN 
           (SELECT SubSystemID 
            FROM IT_COMPLAINTS.ITC_SystemUserMapping 
            WHERE ...)
          ELSE @SubSystemID END)

left outer joinIT_COMPLAINTS.ITC_SystemUserMapping

上考虑CD.SystemID表格CD.SubSystemID

喜欢:

FROM  [IT_COMPLAINTS].[ITC_Casedetails]  CD  WITH (NOLOCK) left outer join
      IT_COMPLAINTS.ITC_SystemUserMapping i on
         CD.SystemID = @SystemID or
         (@SystemID = 0 and 
          CD.SystemID = SystemID and UserID = @UserID AND IsActive = 1 ) and
         CD.SubSystemID = @SubSystemID or
         (CD.SubSystemID = SubSystemID and 
          UserID = @UserID AND IsActive = 1 and 
          (@SystemID = 0 or 
           @SystemID > 0 AND SystemID = @SystemID))

答案 3 :(得分:0)

您可以使用以下查询识别可能导致问题的用户和系统对:

SELECT
    UserID, SystemID,
    count(*) as "Count",
    min(SubSystemID) as minSubSystemID, max(SubSystemID) as maxSubSystemID)
FROM IT_COMPLAINTS.ITC_SystemUserMapping 
WHERE IsActive = 1
GROUP BY UserID, SystemID
HAVING COUNT(*) > 1

我同意@ JamesZ的回答。如果你不喜欢联合和没有from子句的查询,我认为你可以在一个查询中完成。

SELECT SubSystemID 
FROM IT_COMPLAINTS.ITC_SystemUserMapping 
WHERE
    UserID = @UserID AND IsActive = 1 AND 
    (
            @SystemID = 0
        or  SystemID = @SystemID and @SubSystemID = 0
        --  assumes that there's a row in this table with this SubSystemID
        or  SubSystemID = @SubSystemID
    )