存储过程返回多于1组信息

时间:2014-02-26 15:54:58

标签: sql sql-server stored-procedures join

我正在使用SQL Server 2008,我正在尝试只返回一个结果集。

当前存储过程:

ALTER PROCEDURE dbo.Usp_rptofficertotalef2 (@sFromClause  NVARCHAR (1000), 
                                            @sWhereClause NVARCHAR (3000), 
                                            @sOfficerID   VARCHAR(8000)) 
AS 
  BEGIN 
      DECLARE @sSQL NVARCHAR (4000) 

      SET @sSQL = '
      select officer.last_name + '', '' + IsNull (officer.first_name, '''') 
                               as [Officer Name]
           , count (gc_type.code) as [Total GCs]          
        from officer
           , gc_type
           , gc
           , gc_officer_dispatch          
       where (gc.gc_final_type_id = gc_type.gc_type_id) 
         and (officer.officer_id = gc_officer_dispatch.officer_id) 
         and (gc.gc_id = gc_officer_dispatch.gc_id) 
         and (gc.gc_id in (select gc.gc_id ' + @sFromClause + ' ' 
                               + @sWhereClause + '))' 

      IF ( @sOfficerID <> '~' ) 
        BEGIN 
            SET @sSQL = @sSQL + ' and officer.officer_id in ( ' 
                               + @sOfficerID + ' ) ' 
        END 

      SET @sSQL = @sSQL + ' 
         group by 
               officer.officer_id
             , officer.last_name
             , officer.first_name 
         order by 
               officer.last_name
             , officer.first_name'       
  END 

BEGIN 
    DECLARE @vSQL  VARCHAR (8000), 
            @vTemp VARCHAR(8000) 

    CREATE TABLE #tempgctime 
      (gc_id NUMERIC(9)) 

    SET @vTemp = ' insert into #tempGCtime 
                   select gc.gc_id ' + @sFromClause + ' ' + @sWhereClause 
    EXEC (@vTemp) 
    SET @vSQL = 
    'SELECT OFFICER.LAST_NAME + '' '' + isNull(OFFICER.FIRST_NAME,'''') 
                     as OFFICER_NAME
          , isNull(Sum(DateDiff(mi, GC_OFFICER_DISPATCH.ARRIVAL_TIME, GC_OFFICER_DISPATCH.CLEAR_TIME)),0) 
                     as [Total GC Time (Minutes)]                                               
       FROM GC_CATEGORY 
      INNER JOIN 
            GC_TYPE 
         ON GC_CATEGORY.GC_CATEGORY_ID = GC_TYPE.GC_CATEGORY_ID                      
      INNER JOIN 
            GC 
         ON GC_TYPE.GC_TYPE_ID = GC.GC_FINAL_TYPE_ID                       
      INNER JOIN 
            GC_OFFICER_DISPATCH 
         ON GC.GC_ID = GC_OFFICER_DISPATCH.GC_ID                      
      INNER JOIN OFFICER 
         ON GC_OFFICER_DISPATCH.OFFICER_ID = OFFICER.OFFICER_ID               
      WHERE (gc.gc_id in (select isNull(gc_id,-1) from #tempGCTime) ' 

    IF ( @sOfficerID <> '~' ) 
      BEGIN 
          SET @vSQL = @vSQL + ' and officer.officer_id in ( ' 
                      + @sOfficerID + ' ) ' 
      END 

    SET @vSQL = @vSQL + ' ) 
               group by 
                     OFFICER.LAST_NAME + '' '' + isNull(OFFICER.FIRST_NAME,'''')
               order by 
                     OFFICER_NAME'  
    DROP TABLE #tempgctime 
END 

这是使用:

执行的
exec usp_rptOfficerTotalEF 'from GC
                               , GC_TYPE
                               , GC_DISPATCH_LOCATION
                               , ADDRESS
                               , CALL_STATUS
                               , OFFICER'
                         , 'where GC.GC_ID = GC_DISPATCH_LOCATION.GC_ID 
                              and ADDRESS.ADDRESS_ID = GC_DISPATCH_LOCATION.ADDRESS_ID 
                              and GC.GC_FINAL_TYPE_ID = GC_TYPE.GC_TYPE_ID 
                              and GC.CALL_STATUS_ID = CALL_STATUS.CALL_STATUS_ID 
                              and GC.PRIMARY_OFFICER_ID *= OFFICER.OFFICER_ID 
                              and GC.INITIAL_CALL_TIME >= ''12/1/2013'' 
                              and GC.INITIAL_CALL_TIME <= ''2/25/2014 11:59:59 PM'''
                         , '~'

我将清理为exec传递的变量,这不是问题。 问题是这会返回

Officer name | Total GCs
------------------------------------------
Officer 1    | 2
Officer 2    | 1

Officer name | Total GC Time (Minutes)
------------------------------------------
Officer 1    | 27
Officer 2    | 0

我想要实现的是

Officer name | Total GCs  | Total GC Time (Minutes)
------------------------------------------
Officer 1    | 2          | 27
Officer 2    | 1          | 0

为了尝试解决这个问题,我使用了这个:

create table #temp
    ([Officer Name] VARCHAR(100),
     [Officer ID] INT,
     [Total GC] INT,
     [Total GC Time (Minutes)] INT,
     [Total Side Job (Minutes)] INT,
     [Total Arrests] INT);
GO  
SELECT gc.gc_id
  INTO #temp2
  FROM GC
     , GC_TYPE
     , GC_DISPATCH_LOCATION
     , ADDRESS
     , CALL_STATUS
     , OFFICER
 WHERE GC.GC_ID = GC_DISPATCH_LOCATION.GC_ID 
   and ADDRESS.ADDRESS_ID = GC_DISPATCH_LOCATION.ADDRESS_ID 
   and GC.GC_FINAL_TYPE_ID = GC_TYPE.GC_TYPE_ID 
   and GC.CALL_STATUS_ID = CALL_STATUS.CALL_STATUS_ID 
   and GC.PRIMARY_OFFICER_ID *= OFFICER.OFFICER_ID 
   and GC.INITIAL_CALL_TIME >= '12/1/2013' 
   and GC.INITIAL_CALL_TIME <= '2/25/2014 11:59:59 PM'
GO

INSERT INTO #TEMP 
select 
    o.last_name + ', ' + IsNull (o.first_name, '') as [Officer Name],
    o.OFFICER_ID as [Officer ID], 
    count (gt.code) as [Total GCs], 
    NULL as [Total GC Time (Minutes)], 
    NULL as [Total Side Job (Minutes)], 
    NULL as [Total Arrests]
from 
    GC gc INNER JOIN GC_OFFICER_DISPATCH god ON gc.gc_id = god.gc_id
    INNER JOIN OFFICER o ON god.officer_id = o.officer_id
    INNER JOIN GC_TYPE gt ON gc.gc_type_id = gt.gc_type_id
    LEFT JOIN GC_PARTY_INVOLVED gpi ON gc.gc_id = gpi.gc_id    
where 
    gc.gc_id in (SELECT gc_id FROM #temp2)
group by 
    o.officer_id, 
    o.last_name, 
    o.first_name      
order by 
    o.last_name, 
    o.first_name
GO

Create Table #tempGCtime(gc_id numeric(9))
GO
insert into #tempGCtime 
    select gc.gc_id 
      from GC gc 
     INNER JOIN 
           GC_OFFICER_DISPATCH god 
        ON gc.gc_id = god.gc_id 
     INNER JOIN 
           OFFICER o 
        ON god.officer_id = o.officer_id 
     INNER JOIN GC_TYPE gt 
        ON gc.gc_type_id = gt.gc_type_id 
      LEFT JOIN GC_PARTY_INVOLVED gpi 
        ON gc.gc_id = gpi.gc_id 
     where gc.gc_id in (select gc_id 
                          from GC 
                         where INITIAL_CALL_TIME >= '12/1/2013' 
                           and INITIAL_CALL_TIME <= '2/25/2014 11:59:59')
GO

DECLARE @gcid int
DECLARE TableCursor CURSOR FOR
SELECT gc_id FROM #tempGCtime

OPEN TableCursor
FETCH NEXT FROM TableCursor INTO @gcid
WHILE @@FETCH_STATUS = 0

BEGIN

UPDATE #TEMP SET [Total GC Time (Minutes)] = 
(SELECT 
    isNull(Sum(DateDiff(mi, GC_OFFICER_DISPATCH.ARRIVAL_TIME,
                 GC_OFFICER_DISPATCH.CLEAR_TIME)),0) as [Total GC Time (Minutes)]                                
   FROM GC_CATEGORY 
  INNER JOIN GC_TYPE 
     ON GC_CATEGORY.GC_CATEGORY_ID = GC_TYPE.GC_CATEGORY_ID
  INNER JOIN GC 
     ON GC_TYPE.GC_TYPE_ID = GC.GC_FINAL_TYPE_ID 
  INNER JOIN GC_OFFICER_DISPATCH 
     ON GC.GC_ID = GC_OFFICER_DISPATCH.GC_ID
  INNER JOIN OFFICER 
     ON GC_OFFICER_DISPATCH.OFFICER_ID = OFFICER.OFFICER_ID
  WHERE (gc.gc_id in (select isNull(gc_id,-1) 
                       from #tempGCtime)) 
    and #temp.[Officer ID] = (SELECT OFFICER_ID 
                                FROM GC_OFFICER_DISPATCH 
                               WHERE GC_ID in (SELECT gc_id 
                                                 FROM #temp2 
                                                WHERE gc_id = @gcid)))

FETCH NEXT FROM TableCursor INTO @gcid
END
CLOSE TableCursor
DEALLOCATE TableCursor
GO

输出格式正确,但数据不正确。

Officer name | Total GCs  | Total GC Time (Minutes)
------------------------------------------
Officer 1    | 2          | 0
Officer 2    | 1          | 14

有没有更简单的方法来实现这一点,而不是通过游标使用更新? (是的,我知道,人们对游标不屑一顾,但这个查询永远不会有太多数据,因此速度慢不是问题)

0 个答案:

没有答案
相关问题