2010-08-06 79 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