2015-10-06 2 views
0

Мой запрос довольно большой, но для понимания цели я вставляю здесьSubquery вернулся более чем 1 значение даже с оператором 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) 

, когда я комментирую это, мой запрос работает, но, Что проблема с INSubquery и Case здесь?

+0

Я не думаю, что вы можете использовать '' CASE' внутри IN (...) ' – zedfoxus

+3

у вас есть несколько подзапросов в таком состоянии. Один из них возвращает более одного значения. –

+0

Замените эту часть ЛЕВЫМИ СОЕДИНЕНИЯМИ. ON x = y AND .. – Mihai

ответ

2

Как @zedfoxus отметил, что проблема эта часть:

... THEN (SELECT SubSystemID FROM IT_COMPLAINTS.ITC_SystemUserMapping

Поскольку, если это возвращает более чем на 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 
    ) 

Это может потребоваться небольшие изменения, но вы должны получить представление

Вместо этого вам может понадобиться изучить структуру структуры «если существует». Обычно намного проще писать и работать лучше.

0

Кажется, вы бы возвращать несколько значений для SubSystemID без AND SystemID = @SystemID в следующем WHERE пункте:

 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) 

рассмотреть left outer join ИНГ таблицу IT_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)) 
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 
    )  
Смежные вопросы