2012-05-15 55 views
0

我有一個存儲過程,我試圖結合兩個不同的SELECT語句使用UNION ALL,但執行查詢後只返回第一個SELECT的項目。存儲過程聯盟所有問題

我想從第一個和第二個select語句中獲取所有項目。

以下是我有:

CREATE PROCEDURE [dbo].[Report_AllActivitiesOfficesAll] 
    @BeginDate datetime, 
    @EndDate datetime 
AS 
    SET @BeginDate = .dbo.DateOnly(@BeginDate) 
    SET @EndDate = .dbo.DateOnly(@EndDate) 
BEGIN 
    SET NOCOUNT ON; 

    SELECT 
      O.OfficeId, 
      O.OfficeName AS Name, 
      AT.Description AS Activity, 
      SUM(A.Duration) AS [Minutes], 
      CAST(SUM(A.Duration) AS FLOAT)/60 AS [Hours], 
      COUNT(A.ActivityId) AS Activities, 
      COUNT(DISTINCT A.CaseId) AS Cases, 
      MIN(CAST(A.Duration AS FLOAT)/60) AS [Min Time], 
      MAX(CAST(A.Duration AS FLOAT)/60) AS [Max Time], 
      SUM(CAST(A.Duration AS FLOAT)/60)/COUNT(A.ActivityId) AS [Avg Time], 
      SUM(CAST(A.Duration AS FLOAT)/60) AS [TotalHours] 
     FROM Activity A 
      INNER JOIN ActivityType AT ON A.ActivityTypeId = AT.ActivityTypeId 
      INNER JOIN ActivityEntry AE ON A.ActivityEntryId = AE.ActivityEntryId 
      INNER JOIN [Case] C ON A.CaseId = C.CaseId 
      INNER JOIN [Office] O ON AE.OfficeId = O.OfficeId 
      INNER JOIN [User] U ON C.CreatedByUserId = U.UserId 
     WHERE .dbo.DateOnly(AE.ActivityDate) BETWEEN @BeginDate AND @EndDate 
     GROUP BY 
      O.OfficeId, 
      O.OfficeName, 
      AT.Description 

     UNION ALL 

     SELECT 
     O.OfficeId, 
     O.OfficeId AS NonCaseOfficeId, 
     O.OfficeName AS OfficeName, 
     NCAT.Description AS NonCaseActivityType, 
     SUM(NCA.Duration) AS [Minutes], 
     CAST(SUM(NCA.Duration) AS FLOAT)/60 AS [Hours], 
     COUNT(NCA.NonCaseActivityId) AS Activities, 
     MIN(CAST(NCA.Duration AS FLOAT)/60) AS [Min Time], 
     MAX(CAST(NCA.Duration AS FLOAT)/60) AS [Max Time], 
     SUM(CAST(NCA.Duration AS FLOAT)/60)/COUNT(NCA.NonCaseActivityId) AS [Avg Time], 
     SUM(CAST(NCA.Duration AS FLOAT)/60) AS [TotalHours] 
    FROM NonCaseActivity NCA 
     INNER JOIN NonCaseActivityType NCAT ON NCA.NonCaseActivityTypeId = NCAT.NonCaseActivityTypeId 
     INNER JOIN [Office] O ON NCA.OfficeId = O.OfficeId 
     INNER JOIN [User] U ON NCA.UserId = U.UserId 
    WHERE .dbo.DateOnly(NCA.ActivityDate) BETWEEN @BeginDate AND @EndDate 
    GROUP BY 
     O.OfficeId, 
     O.OfficeName, 
     NCAT.Description 
END 
+0

發佈整個存儲過程,必須是其他內容。 – Magnus

+0

@Magnus我剛剛添加了最近更改的完整代碼。 – Masriyah

+0

每個列都有11列,但每列的數據類型必須相同。你有幾列不出現*是相同的數據類型。 –

回答

2

列必須匹配數據類型和內容才能正確有效地使用聯合。您不能在中間更改列名稱。如果您需要知道記錄來自聯盟的哪個部分,請添加另一列來執行此操作。你的不。 Officename位於第二個查詢的第一個和第三個列的第二列。第二個查詢的第二列中的內容極有可能不是第一列的第二列中的數據類型。這不是唯一的不匹配,而是一個例子。

如果您需要在第一個查詢中不需要的第二個查詢中的列,那麼您仍然必須將其放在第一個查詢中。如果你需要第一個你不需要的列,那麼你必須在查詢的那個地方放置一個空值。例如(不是你有什麼一個完全重寫,但足以讓我所談論的想法):

SELECT    
    O.OfficeId,  
    CAST(NULL as int) as NonCaseOfficeId  
    O.OfficeName AS Name,   
    AT.Description AS Activity, 
    COUNT(DISTINCT A.CaseId) AS Cases, 
    cast('Case' as varchar (10)) as recordType   
FROM Activity A   
    INNER JOIN ActivityType AT ON A.ActivityTypeId = AT.ActivityTypeId   
    INNER JOIN ActivityEntry AE ON A.ActivityEntryId = AE.ActivityEntryId   
    INNER JOIN [Case] C ON A.CaseId = C.CaseId   
    INNER JOIN [Office] O ON AE.OfficeId = O.OfficeId   
    INNER JOIN [User] U ON C.CreatedByUserId = U.UserId  
WHERE .dbo.DateOnly(AE.ActivityDate) BETWEEN @BeginDate AND @EndDate   
GROUP BY    
    O.OfficeId,    
    O.OfficeName,    
    AT.Description 
UNION ALL   

SELECT   
    O.OfficeId,   
    O.OfficeId,   
    O.OfficeName,   
    NCAT.Description, 
    cast(NULL as int), 
    'NonCase' 
FROM NonCaseActivity NCA   
    INNER JOIN NonCaseActivityType NCAT 
     ON NCA.NonCaseActivityTypeId = NCAT.NonCaseActivityTypeId 
    INNER JOIN [Office] O ON NCA.OfficeId = O.OfficeId   
    INNER JOIN [User] U ON NCA.UserId = U.UserId  
WHERE .dbo.DateOnly(NCA.ActivityDate) BETWEEN @BeginDate AND @EndDate 

現在因爲查詢也需要從第一次查詢的數據類型,你會看到我專門將其轉換爲我想要的數據類型。您可能需要在聯合的第二部分的空值上執行該操作,以及確保數據類型匹配。如果你沒有指定,我相信SQL服務器假定null是一個int,所以當你需要其他數據類型時,這是最重要的。

+0

感謝您對我的真正感謝。但是我明白了 - 兩個select語句都需要具有相同的數據類型以及命名? – Masriyah

+2

@Amina,數據類型需要匹配,但名稱將使用第一個查詢中的任何內容。 –

+0

@KevinFairchild感謝提示存儲過程執行得很好,但現在我正在獲取非活動列下的所有案例活動。 nonCase活動和案例活動選擇語句的所有結果都列在非活動列名稱下。我如何得到這樣每個選擇語句都有自己的一組列名稱?謝謝 – Masriyah

0

似乎沒什麼問題。請記住,所使用的列名將來自第一個查詢。

所以,如果我用像查詢:

SELECT 1 AS Something 
UNION ALL 
SELECT 2 AS SomethingElse 

我看到的只是結果(1和2)根據現場叫什麼,也不會看到一個名爲SomethingElse場什麼。

也許是這個問題?

嘗試向兩個查詢添加額外的額外字段,以標識它從哪個結果集中提取。

可能爲第一個查詢添加'Activity'AS Source,爲第二個查詢添加'Non-Case Activity'AS Source,以確保您清楚地瞭解顯示內容?

+0

好吧,我會繼續前進,試試看。謝謝! – Masriyah

+0

嘗試了這一點,似乎從這返回的所有項目都是第一個選擇語句中的選擇項,而第二個中沒有任何項。 – Masriyah

+0

您是否嘗試直接運行第二個選擇? –