在SQL中执行此操作的最佳方法是什么(Sybase SQL,如果区别很重要):
表格(包含一些示例数据)
| id | value1 | value2 | version |
==================================
| 1 | A11 | B11 | 1 |
| 1 | A12 | B12 | 2 |
| 2 | A21 | B21 | 1 |
| 3 | A32 | B32 | 2 |
Unique key: (id, version). Index: (id, version)
表中的数据集大小: ~100k行,典型查询的where子句将结果限制为10-100个ID,版本#s为1,2或有时为3。
我需要做什么:每个ID,检索具有该ID最高版本的行
| id | value1 | value2 | version |
==================================
| 1 | A12 | B12 | 2 | <---- Chosen since 2>1 for id=1
| 2 | A21 | B21 | 1 |
| 3 | A32 | B32 | 2 |
简单的解决方案:我能想到的显而易见的方法是使用子查询:
SELECT id, value1, value2
FROM T 'T1'
WHERE id in (1, 2, 3, ... 10) -- Obviously a fake sample clause
AND version = (SELECT MAX(version) FROM T 'T2'
WHERE T1.id=T2.id
AND id in (1, 2, 3, ... 10)
)
问题:这是最好的方法吗?
“最好”在这里意味着:
“平均效果最佳”(给定数据集大小,典型查询大小和上面显示的索引)。
对于具有类似性能的方法,最优雅的代码方式。这显然是旁观者的眼睛,但是如果你能证明代码更具可扩展性/可维护性,那么这就是优雅代码的明确标志。
答案 0 :(得分:2)
SELECT *
FROM (
SELECT id,
value1,
value2,
version,
max(version) over (partition by id) as max_version
FROM T
WHERE id IN (1, 2, 3, ... 10)
) t2
WHERE version = max_version
根据您的DBMS(尤其是优化器)和索引,这可能比子选择更快,因为只需对表进行一次扫描。
答案 1 :(得分:0)
我认为使用JOIN
而不是子查询会使其更具可读性:
SELECT id, value1, value2
FROM T 'T1'
INNER JOIN (
SELECT id,MAX(version) as version
FROM T
WHERE id IN (...)
GROUP BY id) T2
ON (T1.id = T2.id AND T1.version=T2.version)
WHERE T1.id in (1, 2, 3, ... 10)
与原始查询相比,它不应导致任何性能开销/优势。