仅从特定表中选择maxdate行

时间:2014-04-04 06:07:17

标签: sql sql-server sql-server-2008

在此查询中,我有表tProtocol (azdp),其中包含以下属性:ProtocolID(主键),ObjectID(文档ID)和Date。问题是,每个ObjectID可能有许多日期值。我想选择max(Date)分组的ObjectID行。

我在where子句

中尝试了这个
and azdp.Date = (select max(Date), ObjectID from tProtocol group by ObjectID)

它返回错误:

  

当选择列表中只能指定一个表达式时   子查询不是用EXISTS引入的。

我如何用存在来写它?

这是完整的查询(只是为了查看它是什么类型的查询,甚至不尝试运行它)

   select distinct
   @SelectUser AS SelectUser,
   substring(ltrim(rtrim(isnull(piD.AccClient,r1.Brief))),1,5) as subDeb,
   substring(ltrim(rtrim(isnull(piC.AccClient,r2.Brief))),1,5) as subCre,
     @TypeRep as TypeRep,
     @ISP AS ISP,
     azdp.*,
     @NOW AS NOW,
     @DATE AS DATE,
     @BANK AS BANK,
     @USERID AS USERID,
     @BATCHID AS BATCHID,
     @SHABLON AS SHABLON,
     @INVCASSA AS INVCASSA,
     @CCYITOGI AS CCYITOGI,
     @CCYTXT AS CCYTXT, 
     CONFIRMEDTXT = case @CONFIRMED 
                         when 8 then 'Все'
                         else case op1.Confirmed 
                                   when 0   then 'План'
                                   when 1   then 'Факт'
                                   when 101 then 'Фикт'
                                   when 100 then 'Закл' end end,
     ISDOC = abs(#DUAL.N-2),
     #BALANCE.BALANCENAME AS BALANCENAME,
     #BALANCE.BALANCEORDER,
     CCYID = case when #DUAL.N = 1 
                  then s1.SecurityID
                  else s2.CurrencyID end,
     CCYNUMBER = case when #DUAL.N = 1 
                      then s1.Number
                      else s2.Number end,
     CCYSHORT = case when #DUAL.N = 1 
                     then s1.Brief
                     else s2.Brief end,
     CCYNAME = case when #DUAL.N = 1 
                    then s1.Name
                    else s2.Name end,
     CCYDEBAMNT = case when #DUAL.N = 1 then op1.Qty else $0 end,
     CCYCREAMNT = case when #DUAL.N = 1 then $0 else op2.Qty end,
     CCYDEBAMNTBS = case when #DUAL.N = 1 then op1.QtyBs else $0 end,
     CCYCREAMNTBS = case when #DUAL.N = 1 then op2.QtyBs else $0 end,
     CCYDEBQTY = case when #DUAL.N = 1 then 1 else 0 end,
     CCYCREQTY = case when #DUAL.N = 1 then 0 else 1 end,
     DATEISP = op1.OperDate,
     BATCH = bt.Brief,
     BATCHNAME = bt.Name,
     DOCSTATUS = case op1.Confirmed 
                 when 0   then 'План'
                 when 1   then 'Факт'
                 when 101 then 'Фикт'
                 when 100 then 'Закл'
                 else 'Проверь док.' end,
     NUMB = op1.Number,
     OPCODE = op1.OpCode,
     -- Счета сначала из платежных инструкций, потом из проводки
     ACCDEB = case when (substring(r1.Brief,1,5)<>'30102' and substring(r2.Brief,1,5)<>'30102') then ltrim(rtrim(r1.Brief)) else ltrim(rtrim(isnull(piD.AccClient,r1.Brief))) end,
     ACCCRE = case when (substring(r1.Brief,1,5)<>'30102' and substring(r2.Brief,1,5)<>'30102') then ltrim(rtrim(r2.Brief)) else ltrim(rtrim(isnull(piC.AccClient,r2.Brief))) end,
     BICDeb = case when (substring(r1.Brief,1,5)<>'30102' and substring(r2.Brief,1,5)<>'30102') then '' else ltrim(rtrim(isnull(bD.BIC,''))) end,
     BICCre = case when (substring(r1.Brief,1,5)<>'30102' and substring(r2.Brief,1,5)<>'30102') then '' else ltrim(rtrim(isnull(bC.BIC,''))) end,
     DEBAMNT = op1.Qty,
     CREAMNT = op2.Qty,
     AMNT = op1.Qty,
     DEBAMNTBS = op1.QtyBs,
     CREAMNTBS = op2.QtyBs,
     AMNTBS = op1.QtyBs,
     DEBCCY = s1.Number,
     CRECCY = s2.Number,
     USERSHORT = substring(azu.Brief,3,datalength(azu.Brief)-2),
     USERNAME = azu.Name,
     ORDERSTRING1 = case when @SHABLON = 3 then bt.Brief else azu.Brief end, 
     ORDERSTRING2 = case when @SHABLON = 3 then azu.Brief else bt.Brief end, 
     op1.Comment AS COMMENT,
     my = op1.UserID,
     my1 = a.UserID
from #BALANCE --with (nolock index = i1)
join tOperPart op1 with (nolock index = XIE8tOperPart)
  on op1.OperDate = @DATE
 and op1.InstitutionID = @BANKID
 and op1.BalanceID = #BALANCE.BALANCEID
 and op1.AccountingType & 1 = 1
join #BATCH bt --with (nolock index = i1)
  on bt.ID = op1.BatchID
join #CCY s1 --with (nolock index = i1)
  on s1.SecurityID = op1.FundID
join tResource r1 with (nolock index = XPKtResource)
  on r1.ResourceID = op1.ResourceID
join tOperPart op2 with (nolock index = XPKtOperPart)
  on op2.OperationID = op1.OperationID
 and op2.CharType = (-1) * op1.CharType
 and op2.AccountingType & 1 = 1
join tResource r2 with (nolock index = XPKtResource)
  on r2.ResourceID = op2.ResourceID
join tCurrency s2 with (nolock index = XPKtCurrency)
  on s2.CurrencyID = r2.FundID
join #DUAL
  on sign(#DUAL.N) = 1
join tDealTransact qqq
  on qqq.DealTransactID=op1.DealTransactID
 and qqq.UserID in (select ObjectID from tObjClsRelation where ObjClassifierID=@ObjClassifierID4)
left join tObject o with (nolock index = XAK1tObject)
       on o.ID = op1.OperationID
      and o.ObjectTypeID = 22
      and o.InstrumentID = op1.InstrumentID
left join tAudit a with (nolock index = XIE3tAudit)
       on a.ObjectID        = o.ObjectID
      and a.ObjectReference = 1                                                                                                                                                                                                                            
      and a.Action          in (2,5) 
/* закомментировано т. к. может быть несколько записей с одним и тем же временем 
      and a.InDateTime      = (select max(a11.InDateTime)           --Самое последние      изменение
                                 from tAudit   a11    with (nolock index = XIE3tAudit) 
                                where a11.ObjectID  = o.ObjectID 
                                  and a11.ObjectReference = 1
                                  and a11.Action in (2,5)) */
      and a.AuditID      = (select max(a11.AuditID)           -----вместо  предыдущего  подзапроса
                                 from tAudit   a11    with (nolock index = XIE3tAudit) 
                                where a11.ObjectID  = o.ObjectID 
                                  and a11.ObjectReference = 1
                                  and a11.Action in (2,5))
left join tProperty p with (nolock index = XPKtProperty)
       on p.PropType        = 76
      and p.PropVal         = a.Action
  -----------------------------------------------
 inner join tObject azob with (nolock index = XAK1tObject)
         on azob.ID = op1.DealTransactID
 inner join tProtocol azdp with (nolock index = XAK1tProtocol)
         on azdp.ObjectID = azob.ObjectID ---**************************************************добавить максимальную дату
 inner join tTransition aztr with (nolock index = XPKtTransition)
         on aztr.TransitionID = azdp.TransitionID
 inner join tNode azn with (nolock index = XPKtNode)
         on azn.NodeID = aztr.TargetStateID
  left join tProtocolSuspend azps with (nolock index = XPKtProtocolSuspend)
         on azps.ProtocolID = azdp.ProtocolID
  left join tProtocolByUser azpba with (nolock index = XPKtProtocolByUser)
         on azpba.ProtocolID = convert(numeric, azdp.ProtocolID)
  left join tUser           azi   with (nolock index = XPKtUser)
         on azi.UserID       = azpba.UserID 
 inner join tAudit  aza with (nolock index = XPKtAudit) -- sp_helpindex tAudit
             on aza.AuditID = azdp.AuditID
 inner join tUser           azu   with (nolock index = XPKtUser)
         on azu.UserID       = aza.UserID 
 inner join tInstrument azfo with ( nolock index = XPKtInstrument)
             on azfo.InstrumentID = azob.InstrumentID
 inner join tObjClassifier azoc WITH (NOLOCK index=XAK1tDepClassifier)
             on azoc.ObjType = 8
        and azoc.ParentID = @ObjClassifierID
                    and azoc.Brief = azfo.Brief
                    and PATINDEX( ('%' + ltrim(rtrim(azn.Brief)) + '%' ) , azoc.Param)>0 --ltrim(rtrim(azn.Brief)) in (azoc.Param ) --PATINDEX('\%' + azn.Brief + '\%', azoc.Param)>0 -- azoc.Param = azn.Brief
 -- Счёт по дебету и БИК банка отправителя, если это платёж по корсчёту. Меняем счёт только для входящих платежей
 left join tPayInstruct piD with (nolock index = XIE2tPayInstruct)
  on piD.DealTransactID = op1.DealTransactID
 and piD.Type = 2
 and piD.Direct = 1
 and piD.Belong = 1
 left join tRKO_Participant_Sync bD with (nolock index = XPKtRKO_Participant_Sync)
  on piD.BankID = bD.ParticipantID
 -- Счёт по кредиту, если это платёж по корсчёту. Меняем счёт только для исходящих платежей
 left join tPayInstruct piC with (nolock index = XIE2tPayInstruct)
  on piC.DealTransactID = op1.DealTransactID
 and piC.Type = 2
 and piC.Direct = 0
 and piC.Belong = 1
 left join tRKO_Participant_Sync bC with (nolock index = XPKtRKO_Participant_Sync)
  on piC.BankID = bC.ParticipantID

-----------------------------------------------    

--  join #USER u --with (nolock index = i1)
--         on u.UserID - isnull(a.UserID, op1.UserID) = 0
 where op1.CharType = 1
-- and op1.OperationID = 2090001842281
 and ( @CONFIRMED = 8
       or op1.Confirmed = @CONFIRMED )
 and ( #DUAL.N = 1
       or @CCYITOGI = 1 )
 and ( @INVCASSA = 1
       or not exists( select 1
                      from #CASSA --with (nolock index = i1)
                      where (#CASSA.RESOURCEID = op1.ResourceID
                             or #CASSA.RESOURCEID = op2.ResourceID) ))
 and not exists( select 1
                   from tObject   o2 with (nolock index = XAK1tObject),
                        tProtocol p2 with (nolock index = XAK1tProtocol),
                        tAudit    a2 with (nolock index = XPKtAudit)
                  where o2.ID = op1.OperationID
                    and o2.ObjectTypeID = 100
                    and o2.InstrumentID = op1.InstrumentID
                    and p2.ObjectID = o2.ObjectID
                    and a2.AuditID = p2.AuditID
                    and a2.InDateTime > isnull(a.InDateTime, '19000101') )
 and (@CCY<>2 or not( s1.Number = '810' AND s2.Number = '810' ))
 and (@CCY<>1 or ( s1.Number = '810' AND s2.Number = '810' ))

1 个答案:

答案 0 :(得分:2)

;with x as
(
select row_number() over (partition by objectid order by date desc) rn,
+ the rest of your very long query
)
select * from x where rn = 1