我有一张包含以下内容的表格:
每个itemid将有100/1000个事件。我需要的是从表中获取每个独特的itemid值的X最新事件。在这种情况下,X是20,“最新”是最高的偶数。
我以前做的是获取整个表格,并且每个itemid只保留最新的20个。这非常缓慢且效率低下。
编辑:我正在使用opennms和Events表(OpenNMS create.sql):( itemid == nodeID)
create table events (
eventID integer not null,
eventUei varchar(256) not null,
nodeID integer,
eventTime timestamp with time zone not null,
eventHost varchar(256),
eventSource varchar(128) not null,
ipAddr varchar(16),
eventDpName varchar(12) not null,
eventSnmphost varchar(256),
serviceID integer,
eventSnmp varchar(256),
eventParms text,
eventCreateTime timestamp with time zone not null,
eventDescr varchar(4000),
eventLoggroup varchar(32),
eventLogmsg varchar(256),
eventSeverity integer not null,
eventPathOutage varchar(1024),
eventCorrelation varchar(1024),
eventSuppressedCount integer,
eventOperInstruct varchar(1024),
eventAutoAction varchar(256),
eventOperAction varchar(256),
eventOperActionMenuText varchar(64),
eventNotification varchar(128),
eventTticket varchar(128),
eventTticketState integer,
eventForward varchar(256),
eventMouseOverText varchar(64),
eventLog char(1) not null,
eventDisplay char(1) not null,
eventAckUser varchar(256),
eventAckTime timestamp with time zone,
alarmID integer,
constraint pk_eventID primary key (eventID)
);
我的查询非常简单:
SELECT eventid, nodeid, eventseverity, eventtime, eventlogmsg
FROM events
WHERE nodeid IS NOT NULL;
答案 0 :(得分:2)
如果您需要固定数量的“最新”条目,则需要使用窗口函数row_number()(不是rank()
)。但是,如果eventid
恰好是唯一的(itemid
},那么唯一(轻微)的差异就是性能。 (您的问题更新确认了这一点。)
此外,您需要一个子查询,因为在窗口函数之前应用了WHERE
条件:
SELECT itemid, eventid, nodeid, eventseverity, eventtime, eventlogmsg
FROM (
SELECT itemid, eventid, nodeid, eventseverity, eventtime, eventlogmsg
,row_number() OVER (PARTITION BY itemid
ORDER BY eventid DESC NULLS LAST) AS rn
FROM events
WHERE nodeid IS NOT NULL
) sub
WHERE rn <= 20
ORDER BY 1, 2 DESC NULLS LAST;
NULLS LAST
子句仅在eventid
可以为NULL时才相关,在这种情况下,这会将具有NULL值的行排序到末尾。 (你的问题更新规则,因此不需要该条款。)
答案 1 :(得分:1)
我认为这是相当昂贵的,可能有更好的方法,但这样的事情对你有用吗?
select itemid, message
from events e
where eventid in
(select eventid from events f
where e.itemid=f.itemid
order by eventid desc
limit 20)
order by itemid
子查询查找特定itemid的最新项目,外部查询为所有项目执行该项目。 sqlfiddle中有一个模型。
答案 2 :(得分:0)
SELECT * FROM
( SELECT
eventid,
itemid,
message,
rank() OVER (PARTITION BY itemid ORDER BY eventid DESC) AS rnk
FROM your_table)
WHERE rnk <= 20