Ошибка при создании SP с временной таблицей внутри и подзапросом

#sql-server-2008

#sql-server-2008

Вопрос:

Я создал эту временную таблицу в своей процедуре хранения, как вы можете видеть, у меня более 1 записи для одного и того же идентификатора:

 @tmpTableResults
TmpInstallerID      TmpConfirmDate  TmpConfirmLocalTime 
==============      ==============  ===================
173                 2011-11-08      11:45:50
278                 2011-11-04      09:06:26
321                 2011-11-08      13:21:35
321                 2011-11-08      11:44:54
483                 2011-11-08      11:32:00
483                 2011-11-08      11:31:59
645                 2011-11-04      10:03:15
645                 2011-11-04      07:03:15
  

Это результат запроса для создания @tmpTableResults

 DECLARE @tmpTableResults TABLE
(
    TmpInstallerID int,
    TmpConfirmDate date,
    TmpConfirmLocalTime time

)

DECLARE @tmpTableQuery VarChar(800)

SET @tmpTableQuery = 'select FxWorkorder.INSTALLERSYSID, FxWorkorder.CONFIRMDATE, FxWorkorder.CONFIRMLOCALTIME from FxWorkorder   
   join install on FxWorkorder.INSTALLERSYSID = install.sysid 
   join RouteGroupWorkarea on FxWorkorder.WORKAREAGROUPSYSID = RouteGroupWorkarea.IWORKAREA_ID
   join RoutingGroup on RouteGroupWorkarea.IRG_ID = RoutingGroup.IRG_IDENTITY 

   where FxWorkorder.SCHEDULEDDATE > = @StartDate and FxWorkorder.SCHEDULEDDATE <= @EndDate 
    and FxWorkorder.Jobstatus <> "Unassign"
    and FxWorkorder.Jobstatus <> "Route"  
    and install.FOXTELCODE <> ""
    and FxWorkorder.CONFIRMLOCALTIME is not null
    and FxWorkorder.CONFIRMDATE <> ""
    group by FxWorkorder.INSTALLERSYSID, FxWorkorder.CONFIRMDATE, FxWorkorder.CONFIRMLOCALTIME
    order by FxWorkorder.INSTALLERSYSID, FxWorkorder.CONFIRMDATE, FxWorkorder.CONFIRMLOCALTIME desc '

INSERT INTO @tmpTableResults EXEC(@tmpTableQuery)
  

Я создаю другой запрос для получения данных из другой таблицы и только первой записи из временной таблицы для того же INSTALLERSYSID

 SELECT RoutingGroup.SDESCRIPTION, FxWorkorder.INSTALLERSYSID, FxWorkOrder.JOBSTATUS, Install.FOXTELCODE, 
    install.NAME, FxWorkOrder.ScheduledDate,
    count(*) as TotalJobs, COUNT(CONFIRMDATE) as ConfirmedJobs,
    (select TmpInstallerID, TmpConfirmDate, TmpConfirmLocalTime from @tmpTableResults where TmpInstallerID = FxWorkorder.INSTALLERSYSID)

from FxWorkorder 
   join install on fxworkorder.INSTALLERSYSID = install.sysid 
   join RouteGroupWorkarea on FxWorkOrder.WORKAREAGROUPSYSID = RouteGroupWorkarea.IWORKAREA_ID
   join RoutingGroup on  RouteGroupWorkarea.IRG_ID = RoutingGroup.IRG_IDENTITY 

where FxWorkorder.SCHEDULEDDATE  > = @StartDate and  FxWorkorder.SCHEDULEDDATE <= @EndDate  
    and FxWorkOrder.Jobstatus <> 'Unassign' 
    and FxWorkOrder.Jobstatus <> 'Route'  
    and Install.FOXTELCODE <> ''
group by RoutingGroup.SDESCRIPTION,FxWorkOrder.INSTALLERSYSID, FxWorkOrder.JOBSTATUS, Install.FOXTELCODE,install.NAME, FxWorkOrder.ScheduledDate,FxWorkOrder.WORKAREAGROUPSYSID
  

Когда я попытался сохранить sp, я получил ошибку

«В списке выбора может быть указано только одно выражение, если подзапрос не введен с помощью EXISTS». Я не могу понять, почему я получил эту ошибку. Но если я выполняю запрос в sql, который работает. Может кто-нибудь увидеть ошибку?

Ответ №1:

Я не знаю, как ваш второй запрос работает для вас ‘в sql’ (где это должно быть? вы имеете в виду SSMS = SQL Server Management Studio?), но я уверен, что это не может работать ни в одной версии SQL Server, которая существует на данный момент. Это из-за этого подзапроса в списке ВЫБОРА:

  (select TmpInstallerID, TmpConfirmDate, TmpConfirmLocalTime from @tmpTableResults where TmpInstallerID = FxWorkorder.INSTALLERSYSID)
  

Дело в том, что каждое выражение в предложении SELECT должно быть скалярным, но этот подзапрос возвращает строку из более чем одного значения. Даже если это только одна строка, это незаконно, потому что возвращает несколько столбцов. Подзапрос в этом контексте должен возвращать не более одного значения, т. Е. это должен быть один столбец, а полученный результат должен содержать либо отсутствие строк, либо только одну.

Вместо этого вы могли бы попробовать этот запрос (хотя я не совсем уверен, не зная более подробной информации о вашей схеме):

 SELECT
    RoutingGroup.SDESCRIPTION,
    FxWorkorder.INSTALLERSYSID,
    FxWorkOrder.JOBSTATUS,
    Install.FOXTELCODE, 
    install.NAME, FxWorkOrder.ScheduledDate,
    count(*) as TotalJobs, COUNT(CONFIRMDATE) as ConfirmedJobs,
    tmp.TmpInstallerID,
    tmp.TmpConfirmDate,
    tmp.TmpConfirmLocalTime

from FxWorkorder 
   join install on fxworkorder.INSTALLERSYSID = install.sysid 
   join RouteGroupWorkarea on FxWorkOrder.WORKAREAGROUPSYSID = RouteGroupWorkarea.IWORKAREA_ID
   join RoutingGroup on  RouteGroupWorkarea.IRG_ID = RoutingGroup.IRG_IDENTITY 
   join @tmpTableResults tmp ON tmp.TmpInstallerID = FxWorkorder.INSTALLERSYSID

where FxWorkorder.SCHEDULEDDATE  > = @StartDate
    and FxWorkorder.SCHEDULEDDATE <= @EndDate  
    and FxWorkOrder.Jobstatus <> 'Unassign' 
    and FxWorkOrder.Jobstatus <> 'Route'  
    and Install.FOXTELCODE <> ''
group by
  RoutingGroup.SDESCRIPTION,
  FxWorkOrder.INSTALLERSYSID,
  FxWorkOrder.JOBSTATUS,
  Install.FOXTELCODE,install.NAME,
  FxWorkOrder.ScheduledDate,
  FxWorkOrder.WORKAREAGROUPSYSID
  tmp.TmpInstallerID,
  tmp.TmpConfirmDate,
  tmp.TmpConfirmLocalTime
  

То есть я добавил еще одно соединение, то, которое к @tmpTableResults , а также добавил столбцы, которые вы пытались извлечь в SELECT предложение и в GROUP BY предложение.

Кроме того, на вашем месте я бы рассмотрел возможность использования коротких псевдонимов для таблиц, подобных этому:

 SELECT
    …
    wo.INSTALLERSYSID,
    wo.JOBSTATUS,
    …
from FxWorkorder wo
   join 

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

Комментарии:

1. Хорошо, спасибо, но результат этого не такой, какой мне нужен, я очень усложняюсь с этим sp, и я решил создать простой с дублирующимися записями, и я хочу разобраться с этим в SSRS, я понятия не имею, что я смогу сгруппировать в SSRS и показывать только итоги для группы.