2015-10-06 62 views
0

我的查詢是相當大的,但對於理解目的,我貼在這裏子查詢與IN操作符返回多個值甚至

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,'')[email protected]) 
      AND (ISNULL(@Mon,'')=''   OR ISNULL(CD.AnalysisMonth,'')[email protected]) 
      AND (IsNull(@Year,0)=0    OR ISNULL(CD.AnalysisYear,'')[email protected]) 

--  
      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,'')[email protected]) 
      AND (ISNULL(@ITCommentID,0)=0  OR ISNULL(CD.ITCommentID,'')[email protected]) 

然而,當我運行它,它給了我一個錯誤

子查詢返回了超過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) 
當我評論這個

,我的查詢工作,但什麼用INSubqueryCase這裏的問題?

+0

我不認爲你可以在'IN(...)'中使用'CASE' – zedfoxus

+3

在這種情況下你有多個子查詢。其中之一是返回多個價值。 –

+0

用左連接替換該零件。 ON x = y AND .. – Mihai

回答

2

像@zedfoxus評論說,問題是這一部分:

... THEN(SELECT SubSystemID FROM IT_COMPLAINTS.ITC_SystemUserMapping

,因爲如果返回多個值,也沒有地方放的是。值你應該是這樣的替換此:

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」類結構。編寫和執行通常要簡單得多。

0

看來你將以下WHERE子句中爲SubSystemID返回多個值不AND SystemID = @SystemID

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

而在這種情況下,它將是'AND SystemID = 0' – Morpheus

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) 

考慮CD.SystemIDleft outer join ING表IT_COMPLAINTS.ITC_SystemUserMappingCD.SubSystemID

like:

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)) 
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 
    )