查找表中每个id的最后5个结果(按eventdate排序)

时间:2017-01-30 20:59:58

标签: sql excel vba postgresql excel-vba

我需要为测试表中的每个id找到最后5个结果(按eventdate排序)

该表格在下面的示例图片中构成,该图片仅显示来自1个id记录的数据,其中有数千个不同的id都具有不同的时间结果,因此为什么我只想要最后5个被退回

enter image description here

我有以下几乎正确的查询,但它包括num_result = 0和auditflag = 2的计数< 6(当然,我的代码是我的新手)

// TODO Spin-wait first.

我只是想找到匹配的最后5条记录,即以黄色突出显示 - 来自那些带有num_result>的记录的最后5条记录0和auditflag = 1

SQL查询使用visoledb

在Excel VBA中编写,连接到PG数据库

3 个答案:

答案 0 :(得分:0)

如果我理解正确,这基本上就是你的查询:

SELECT q1.id, q1.eventdate, q1.num_result 
FROM test q1 INNER JOIN
     test q2
     ON q1.id = q2.id AND
        q1.eventdate <= q2.eventdate AND q1.auditflag = 1 
WHERE q1.num_result > 0
GROUP BY q1.id, q1.eventdate, q1.num_result 
ORDER BY q1.id, q1.eventdate DESC ;

我认为您希望将此作为基本查询:

SELECT q.id, q.eventdate,
       SUM( (q.auditflag = 1)::int) OVER (PARTITION BY q.id ORDER BY event_date) as num_result
FROM test q;

我认为您希望使用过滤器:

SELECT q.*
FROM (SELECT q.id, q.eventdate,
             SUM( (q.auditflag = 1)::int) OVER (PARTITION BY q.id ORDER BY event_date DESC) as num_result
     FROM test q
    ) q
WHERE num_result <= 5;

答案 1 :(得分:0)

此类查询通常使用window functions解决,例如:

@import "//cloud.typography.com/6741734/7240552/css/fonts.css";

但这肯定会导致整个表格的顺序扫描。其中(如您所述)每SELECT id, eventdate, num_result FROM (SELECT id, eventdate, num_result, row_number() OVER (PARTITION BY id ORDER BY eventdate) FROM test WHERE num_result > 0 AND auditflag = 1) q WHERE row_number <= 5 ORDER BY id, eventdate DESC 有数千行,您只需要最后5行。使用LATERAL subqueries查询时,此分布的查询速度更快:

id

对于索引,SELECT id, eventdate, num_result FROM (SELECT DISTINCT id FROM test) q -- above use a table where "id" is a unique (primary) key -- f.ex. where "test.id" refers to if it's a foreign key LEFT JOIN LATERAL (SELECT eventdate, num_result FROM test WHERE id = q.id AND num_result > 0 AND auditflag = 1 ORDER BY eventdate DESC LIMIT 5) l ON TRUE 上的id, eventdate DESC索引会有很大帮助(同样,你可以使test成为partial)。

答案 2 :(得分:0)

这是最终对我有用的代码,尽管我必须使用身份字段(全局审计序列和唯一记录标识符)。直到我问为什么没有任何工作,我才知道这一点,但希望答案可以帮助别人。感谢所有帮助我的人。

select id, eventdate, num_result
from test
where test.identity IN
  (select top 5 identity from test as q1
  where q1.id=test.id and q1.auditflag=1 and q1.num_result>0 
  order by q1.eventdate desc)
order by id, eventdate desc