我尝试解决 SQL 问题的方法是循序渐进。
- 您希望每个产品的最大主要版本对应的最大次要版本的最大修订版本。
每个产品的最大主编号由下式给出:
SELECT Name, MAX(major) AS Major FROM CA GROUP BY Name;
因此,每个产品的最大主编号对应的最大次编号由下式给出:
SELECT CA.Name, CA.Major, MAX(CA.Minor) AS Minor
FROM CA
JOIN (SELECT Name, MAX(Major) AS Major
FROM CA
GROUP BY Name
) AS CB
ON CA.Name = CB.Name AND CA.Major = CB.Major
GROUP BY CA.Name, CA.Major;
因此,最大修订版(对于每个产品的最大主版本号对应的最大次版本号)由下式给出:
SELECT CA.Name, CA.Major, CA.Minor, MAX(CA.Revision) AS Revision
FROM CA
JOIN (SELECT CA.Name, CA.Major, MAX(CA.Minor) AS Minor
FROM CA
JOIN (SELECT Name, MAX(Major) AS Major
FROM CA
GROUP BY Name
) AS CB
ON CA.Name = CB.Name AND CA.Major = CB.Major
GROUP BY CA.Name, CA.Major
) AS CC
ON CA.Name = CC.Name AND CA.Major = CC.Major AND CA.Minor = CC.Minor
GROUP BY CA.Name, CA.Major, CA.Minor;
经过测试 - 它可以工作并产生与 Andomar 的 query 相同的答案。
性能
我创建了更大的数据量(11616 行数据),并针对我的查询运行了 Andomar 的基准时间 - 目标 DBMS 是在 MacOS X 10.7.2 上运行的 IBM Informix Dynamic Server (IDS) 版本 11.70.FC2。我使用了 Andomar 的两个查询中的第一个,因为 IDS 不支持第二个查询中的比较符号。我加载了数据,更新了统计数据,并运行了我的查询,然后是 Andomar,然后是 Andomar,然后是我的。我还记录了 IDS 优化器报告的基本成本。两个查询的结果数据相同(因此查询都准确 - 或同样不准确)。
表未索引:
Andomar's query Jonathan's query
Time: 22.074129 Time: 0.085803
Estimated Cost: 2468070 Estimated Cost: 22673
Estimated # of Rows Returned: 5808 Estimated # of Rows Returned: 132
Temporary Files Required For: Order By Temporary Files Required For: Group By
具有唯一索引的表(名称、主要、次要、修订):
Andomar's query Jonathan's query
Time: 0.768309 Time: 0.060380
Estimated Cost: 31754 Estimated Cost: 2329
Estimated # of Rows Returned: 5808 Estimated # of Rows Returned: 139
Temporary Files Required For: Group By
如您所见,索引显着提高了 Andomar 查询的性能,但在这个系统上它似乎仍然比我的查询更昂贵。该索引为我的查询节省了 25% 的时间。我很想看到两个版本的 Andomar 查询的可比较数据,可比较的数据量,有和没有索引。 (如果需要我的测试数据可以提供;一共有132个产品——问题中列出的3个和新的129个;每个新产品有(相同的)90个版本条目。)
产生差异的原因是Andomar的查询中的子查询是一个相关的子查询,这是一个相对昂贵的过程(在缺少索引的情况下更是如此)。