在此查询中,我有表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' ))
答案 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