2014-02-10 149 views
1

我有下面的表X最新行:選擇一列的每個唯一值

  • 事件ID - >主鍵,數字越大表示新
  • 的itemid - >外鍵的項目表
  • 消息 - >事件消息

將有100 /對於每個的itemid事件1000。我需要的是從表中爲itemid的每個唯一值獲取X個最新事件。在這種情況下,X是20,「最新」是最高的eventid。

我之前做的是獲取整個表格,只保留每個itemid最新的20個。這是非常緩慢和低效的。

編輯:我使用的OpenNMS和事件表(OpenNMS create.sql):(itemid的==節點ID)

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; 
+1

你可以發佈你的表結構爲'CREATE TABLE ...',數據示例和你現有的查詢嗎? –

+0

@IgorRomanchenko編輯了這些細節的帖子 – Smitty

回答

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

我會想象它是相當昂貴的,並且可能有更好的方法,但是這樣的事情對你有用嗎?

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有一個模型。

0
SELECT * FROM 
(SELECT 
    eventid, 
    itemid, 
    message, 
    rank() OVER (PARTITION BY itemid ORDER BY eventid DESC) AS rnk 
    FROM your_table) 
WHERE rnk <= 20