2010-08-06 76 views
1

我需要一些帮助来查询 - 我正在使用Firebird 2.1。SQL查询帮助 - 需要一些魔力

我有一个表,如:

RowID (primary key) | ActivityID | Duration | BilledAt 

1 | 1 | 50 | 06.08.2010, 14:05:00.598 
2 | 1 | 70 | 06.08.2010, 14:05:00.608 
3 | 2 | 30 | 06.08.2010, 14:05:00.598 
4 | 3 | 40 | 06.08.2010, 14:05:00.598 
5 | 3 | 50 | 06.08.2010, 14:05:00.608 

我想获得每个ActivityID的持续时间,但如果有可以用同ActivityID不止一个项目,我需要得到一个与最高BilledAt值。 (最近的条目)

如果我执行:

SELECT ActivityID, Max(BilledAt) 
FROM BilledTime 
GROUP BY ActivityID; 

我会得到什么,我想没有时间值。如果我在GROUP BY子句中包含Duration列,那么将选择多个ActivityID。

有没有一个优雅的解决方案呢?

谢谢!

回答

3

不熟悉火鸟所以语法可能是错误的,但这应该工作:

SELECT a.ActivityID, a.Duration, a.BilledAt 
FROM BilledTime a 
LEFT JOIN BilledTime b on a.ActivityID = b.ActivityID AND b.BilledAt > a.BilledAt 
WHERE b.ActivityID IS NULL 

另外,您可以用更直观的WHERE NOT EXISTS子查询,而不是LEFT JOIN,但我相信上面的两端速度更快。

+0

这是非常好的。我总是使用另一种方法比较“MAX”。但我试了一下,发现左连接的表现要好得多。我没有Firebird,但是我在Oracle上尝试了一个相当大的DB,虽然报告的成本(使用Explain Plan)是4倍,但有效时间仅为1/4(1秒而不是4秒)。 – hol 2010-08-06 14:19:43

1

我会做这样的

SELECT a.ActivityID, a.Duration, a.BilledAt 
FROM BilledTime a 
WHERE a.BilledAt = (select max(b.billedAt) from BilledTime b where b.ActivityId = a.ActivityID) 
+0

这个也适用。感谢你们俩! – Steve 2010-08-06 13:56:29