2014-04-04 116 views
0

在此查詢中,我具有表tProtocol (azdp),它具有屬性:ProtocolID(主鍵),ObjectID(文檔的ID)和Date。問題是,每個ObjectID可能有很多日期值。我想選max(Date)行,按ObjectID分組。僅從特定表中選擇maxdate行

Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

如何我存在寫:

我在where子句

and azdp.Date = (select max(Date), ObjectID from tProtocol group by ObjectID) 

它返回的錯誤嘗試這樣做?

下面是完整的查詢(只是看到什麼樣的查詢是它,甚至不嘗試運行它)

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 [email protected]) 
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

它會返回錯誤,你的子查詢將返回多行&你正在比較=子句。它將如何工作?或者使用IN而不是=,或者在子查詢中使用移除組。完全取決於你想要的。 – AK47

回答

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 
+0

似乎正是我需要的。謝謝。但它返回錯誤:關鍵字'with'附近的語法不正確。如果此語句是公用表表達式,xmlnamespaces子句或變更跟蹤上下文子句,則前面的語句必須以分號結尾。 –

+0

@SherzodMuminov是正確的,如果有更多的腳本,你需要以分號開頭。我在分句中加了分號,現在試試 –

+0

完成))謝謝)) –