如何找到最大数量的表

时间:2017-03-14 02:04:13

标签: sql oracle

在甲骨文中,我必须找到所有船只的名称,这些船只的枪支数量对于同一口径的船只来说是最大的。船名在船舶表中,枪支和钻孔尺寸在类表中。

Create Table Classes (
    class Varchar(40),
    type Char (2),
    country Varchar(15),
    numGuns Int,
    bore Int,
    displacement Int
);
Create Table Ships (
    name Varchar(40),
    class Varchar(40),
    launched Int
);

我一直在考虑做的一件事是加入船只和类,然后使用相关的子查询。我尝试过这样做,但我做的一切似乎都没有用。以下是我尝试过的内容:

Select DISTINCT name
From Classes T1, Classes T2, Ships
Where T1.bore = T2.bore AND T1.numGuns = 
    (Select MAX(X.numGuns)
    From Classes X, Classes Y
    Where X.bore = Y.bore);

然而,结果给了我太多的船只,那么它有什么问题呢?

1 个答案:

答案 0 :(得分:0)

根据您的数据集,不同的方法可能会产生不同的性能和成本配置文件。

在装载了一些小数据(我的船只知识缺乏这些例子)之后,独木舟和划艇与更多的枪绑在一起,但是相同的钻孔和双体船比IronClads有更多的枪但是同样的钻孔:

INSERT INTO CLASSES VALUES('Clipper','CT','UK',7,3,3);
INSERT INTO CLASSES VALUES('Canoe','CO','JP',19,3,9);
INSERT INTO CLASSES VALUES('Rowboat','CO','KO',19,3,95);
INSERT INTO CLASSES VALUES('IronClad','IC','MG',3,11,4);
INSERT INTO CLASSES VALUES('Catamaran','CA','FR',9,11,6);
INSERT INTO SHIPS VALUES ('Cutty Sark','Clipper',9);
INSERT INTO SHIPS VALUES ('HMS Canoe','Canoe',11);
INSERT INTO SHIPS VALUES ('SS Boat','Rowboat',77);
INSERT INTO SHIPS VALUES ('USS Boat','Canoe',33);
INSERT INTO SHIPS VALUES ('Dreadnought','IronClad',12);
INSERT INTO SHIPS VALUES ('Boaty','Catamaran',19);
INSERT INTO SHIPS VALUES ('McBoatFace','Catamaran',23);
COMMIT;

这种查询有多种方法。我将概述一些使用内联视图的示例,但其他模式也可以使用。

我在查看这些数据时遇到的一个问题是,您希望如何处理两个具有相同枪支数量和相同孔径的类别之间的联系。
如果您想确保每CLASS只包含一个BORE(如果您想要断开关系),则可以使用KEEP子句进行聚合。请注意,如果存在关系,这将强制执行 以下内容会查找CLASS BORE GUNS SHIPSCLASS SELECT BORE_MAX_GUN.BORE, BORE_MAX_GUN.MAX_GUN_CLASS, SHIPS.NAME FROM SHIPS INNER JOIN (SELECT BORE, MAX(CLASS) KEEP (DENSE_RANK LAST ORDER BY NUMGUNS ASC) AS MAX_GUN_CLASS FROM CLASSES GROUP BY BORE) BORE_MAX_GUN ON SHIPS.CLASS = BORE_MAX_GUN.MAX_GUN_CLASS ORDER BY 1 ASC, 2 ASC, 3 ASC; BORE MAX_GUN_CLASS NAME 3 Rowboat SS Boat 11 Catamaran Boaty 11 Catamaran McBoatFace 。 (如果我正确理解了预期的查询)

SELECT 
BORE_MAX_GUN.BORE,
BORE_MAX_GUN.CLASS,  SHIPS.NAME 
FROM SHIPS
INNER JOIN
(SELECT BORE,
CLASS,
DENSE_RANK() OVER (PARTITION BY BORE ORDER BY NUMGUNS DESC) AS GUN_RANK
FROM CLASSES)  BORE_MAX_GUN
ON SHIPS.CLASS = BORE_MAX_GUN.CLASS
AND BORE_MAX_GUN.GUN_RANK = 1
ORDER BY 1 ASC, 2 ASC, 3 ASC;

返回:

BORE  CLASS      NAME
3     Canoe      HMS Canoe
3     Canoe      USS Boat
3     Rowboat    SS Boat
11    Catamaran  Boaty
11    Catamaran  McBoatFace

在这些数据中,双体船的枪支数量超过了IronClads,Canoes / Rowboats比快船更多。 Canoe和Rowboat之间的关系按字母顺序排列,并返回每个Bore最多枪支的所有船只。

如果你想保持枪支数量的关系,你可以改用分析函数:

{{1}}

返回:

{{1}}

以上将获取所有类别,包括关系,其孔径最大的枪支,并返回每个类别的所有船只。在这个数据集中,包括Canoes和Rowboats,但Clippers不是。

各种方法的性能可能不同,因此建议进行基准测试,但希望这些可能是一个起点。