使用MS_SQL
我有一个查询,我试图从未来事件列表中仅返回NEXT事件(基于今天的日期) - 因此数据库中的记录(entity_name)可能会有多个未来事件发生。
到目前为止,这是我的代码:
select fut.event_id, ent.entity_name, evt.event_datetime_utc
from evt_v1.ce_events_coverage_future fut
left join evt_v1.ce_events evt
on evt.event_id=fut.event_id
left join edm_v1.edm_entity ent
on ent.factset_entity_id=fut.factset_entity_id
left join edm_v1.edm_security_entity_map map
on map.factset_entity_id=ent.factset_entity_id
left join evt_v1.ce_event_types typ
on typ.event_type=evt.event_type
left join evt_v1.ce_market_times mkt
on mkt.market_time=evt.market_time
left join evt_v1.ce_fiscal_periods fis
on fis.fiscal_period=evt.fiscal_period
where map.isin in
('US38259P5089',
'US0378331005')
and evt.event_type='ER'
and evt.event_datetime >=GetDate()
order by ent.entity_name asc, event_datetime asc
返回以下结果:
event_id entity_name event_datetime_utc
4097237 APPLE INC 2014-04-22 00:00:00.000
4188165 APPLE INC 2014-07-22 00:00:00.000
4270116 APPLE INC 2014-10-20 00:00:00.000
4339538 APPLE INC 2015-01-20 00:00:00.000
4097141 GOOGLE INC 2014-04-16 00:00:00.000
4188066 GOOGLE INC 2014-07-17 00:00:00.000
4269906 GOOGLE INC 2014-10-16 00:00:00.000
4339013 GOOGLE INC 2015-01-22 00:00:00.000
我想要返回的是每个entity_name最迫切的记录:
4097237 APPLE INC 2014-04-22 00:00:00.000
4097141 GOOGLE INC 2014-04-16 00:00:00.000
我确信这很简单,但我不确定这是否最好通过使用DATE函数或某种RANK函数(或两者都没有!)?
先谢谢你的帮助, 即
答案 0 :(得分:2)
您可以使用rank()
或row_number()
:
with t as (<your query here>)
select event_id, entity_name, event_datetime_utc
from (select t.*,
row_number() over (partition by entity_name
order by event_datetime_utc asc
) as seqnum
from t
) t
where seqnum = 1;
答案 1 :(得分:0)
首先,您可以使用子查询来查找这些值。这取决于evt_v1.ce_events.event_datetime
不为空的假设。此外,如果确定“next”需要map.isin上的附加条件,则只需展开子查询即可。
Select fut.event_id, ent.entity_name, evt.event_datetime_utc
From evt_v1.ce_events_coverage_future As fut
Join evt_v1.ce_events As evt
On evt.event_id = fut.event_id
Join edm_v1.edm_entity As ent
On ent.factset_entity_id = fut.factset_entity_id
Join edm_v1.edm_security_entity_map As map
On map.factset_entity_id = ent.factset_entity_id
Left Join evt_v1.ce_event_types As typ
On typ.event_type = evt.event_type
Left Join evt_v1.ce_market_times As mkt
On mkt.market_time = evt.market_time
Left Join evt_v1.ce_fiscal_periods As fis
On fis.fiscal_period = evt.fiscal_period
Where map.isin In( 'US38259P5089','US0378331005' )
And evt.event_type = 'ER'
And evt.event_datetime = (
Select Min( evt1.event_datetime )
From evt_v1.ce_events_coverage_future As fut1
Join evt_v1.ce_events As evt1
On evt1.event_id = fut1.event_id
Join edm_v1.edm_entity As ent1
On ent1.factset_entity_id = fut1.factset_entity_id
Where ent1.entity_name = ent.entity_name
And evt1.event_datetime >= CURRENT_TIMESTAMP
)
Order By ent.entity_name Asc, evt.event_datetime Asc
其次,你已经在很多地方使用了Left Joins,它们没有任何区别。具体来说,您在edm_v1.edm_security_entity_map
上有一个左连接,但在Where子句中,您要求map.isin
凭借您的In函数具有值,从而有效地将此Left Join转换为内部Join。 edm_v1.edm_security_entity_map
表也是如此。