帮助 SQL 查询 - 需要一些魔法
Posted
技术标签:
【中文标题】帮助 SQL 查询 - 需要一些魔法【英文标题】:Help with SQL query - some magic needed 【发布时间】:2011-03-26 08:28:39 【问题描述】:我在查询方面需要一些帮助 - 我使用的是 Firebird 2.1。
我有一张这样的桌子:
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;
没有 Duration 值,我会得到我想要的。如果我在 GROUP BY 子句中包含 Duration 列,则会选择多个 ActivityID。
有没有优雅的解决方案?
谢谢!
【问题讨论】:
【参考方案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)
【讨论】:
【参考方案2】:不熟悉 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,但我相信上述方法最终会更快。
【讨论】:
这真是太好了。与“MAX”相比,我总是使用另一种方法。但我试了一下,发现左连接的性能要好得多。我没有 Firebird,但我尝试使用具有相当大数据库的 Oracle,虽然报告的成本(使用解释计划)是 4 倍,但有效时间仅为 1/4(1 秒而不是 4 秒)。以上是关于帮助 SQL 查询 - 需要一些魔法的主要内容,如果未能解决你的问题,请参考以下文章