0

SELECTを使用して2つの異なるステートメントを結合しようとしているストアドプロシージャがありUNION ALLますが、クエリが実行された後、最初のアイテムのみSELECTが返されます。

最初と2番目の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
4

2 に答える 2

2

ユニオンを正しく効果的に使用するには、列のデータ型と内容が一致している必要があります。途中で列名を変更することはできません。レコードがユニオンのどの部分から来たかを知る必要がある場合は、別の列を追加してください。あなたのものはしません。Officename は、最初のクエリの 2 列目と 2 番目のクエリの 3 列目にあります。2 番目のクエリの 2 番目の列にあるものは、最初のクエリの 2 番目の列と同じデータ型ではない可能性が高くなります。これは唯一の不一致ではなく、例です。

最初のクエリでは不要な列が 2 番目のクエリで必要な場合でも、最初のクエリに含める必要があります。また、最初の列に必要な列が 2 番目の列には必要ない場合は、クエリのその場所に null 値を配置する必要があります。例(あなたが持っているものを完全に書き直すわけではありませんが、私が話していることを理解するには十分です):

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   

クエリも最初のクエリからデータ型を取得するため、必要なデータ型に具体的にキャストしたことがわかります。データ型が一致していることを確認するだけでなく、ユニオンの2番目の部分のnullでそれを行う必要がある場合があります。指定しない場合、nullはSQLサーバーによってintであると想定されるため、他のデータ型が必要な場合はこれが最も重要です。

于 2012-05-15T20:17:46.523 に答える
0

私には問題ないようです。使用される列名は最初のクエリから取得されることに注意してください。

したがって、次のようなクエリを使用した場合:

SELECT 1 AS Something
UNION ALL
SELECT 2 AS SomethingElse

Something というフィールドの下には結果 (1 と 2) だけが表示され、SomethingElse というフィールドには何も表示されません。

おそらくそれが問題ですか?

プル元の結果セットを識別する余分なフィールドを両方のクエリに追加してみてください。

最初のクエリに「アクティビティ」AS ソースを追加し、2 番目のクエリに「非ケース アクティビティ」AS ソースを追加して、何が表示されているかを明確に把握できるようにしますか?

于 2012-05-15T18:49:52.260 に答える