2010-08-06 3 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, тогда выбираются несколько идентификаторов активности.

Есть ли элегантное решение?

Спасибо!

ответ

3

Не знакомы с Firebird, так что синтаксис может быть неправильным, но это должно работать:

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 с довольно большой БД, и хотя сообщаемые затраты (с использованием Объяснительного плана) в 4 раза выше, эффективное время составляет всего 1/4 (1 сек. Вместо 4 сек.). – hol

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

Смежные вопросы