【发布时间】:2016-07-26 03:23:04
【问题描述】:
我的数据库如下所示:
峰(姓名、海拔高度、差值、地图、地区)
登山者(姓名、性别)
参加(TRIP_ID、姓名)
爬升(TRIP_ID、PEAK、WHEN)
- PEAK 提供有关用户感兴趣的山峰的信息。该表列出了每个山峰的名称、海拔(以英尺为单位)、难度级别(1-5 级)、地图位于及其所在的内华达山脉地区。
- CLIMBER 列出了俱乐部的成员,并给出了他们的姓名和性别。
- PARTICIPATED 提供了参加过各种登山旅行的登山者的集合。每次旅行的参与者人数各不相同。
- CLIMBED 会根据每座山峰的攀登数据,告诉您每次攀登过程中攀登了哪些山峰。
我需要为这 2 个示例场景编写 SQL 查询的帮助:
- 计算俱乐部中男性和俱乐部中女性的平均峰数。
- 玛丽亚攀登过的每一座山峰都有哪些人攀登?
- 谁在大约 60 天内攀登了 20 多座山峰?
编辑:第一个查询现在可以工作,看起来像这样:
SELECT SEX, AVG(num_peaks) AS avg_peaks
FROM
(
SELECT CLIMBER.*, COUNT(CLIMBED.PEAK) num_peaks
FROM CLIMBED
INNER JOIN PARTICIPATED
ON PARTICIPATED.TRIP_ID = CLIMBED.TRIP_ID
RIGHT OUTER JOIN CLIMBER
ON CLIMBER.NAME = PARTICIPATED.NAME
GROUP BY CLIMBER.NAME, CLIMBER.SEX
)
GROUP BY SEX;
此查询为我提供了男性和女性攀登的山峰总数。但我似乎无法弄清楚如何获得平均值而不是计数。我知道你不能简单地将 COUNT 函数更改为 AVG b/c 我的数据是字符串形式而不是整数。
我的第二个查询如下所示:
SELECT DISTINCT PARTICIPATED.NAME
FROM PARTICIPATED
INNER JOIN CLIMBED
ON PARTICIPATED.TRIP_ID = CLIMBED.TRIP_ID
WHERE CLIMBED.PEAK IN
(
SELECT CLIMBED.PEAK
FROM CLIMBED
INNER JOIN PARTICIPATED
ON PARTICIPATED.TRIP_ID = CLIMBED.TRIP_ID
WHERE NAME IN ('MARIA')
)
AND PARTICIPATED.NAME NOT IN ('MARIA');
该查询为我提供了所有攀登过 Maria 也攀登过的山峰的人,但并没有只提供已经攀登过 Maria 已经攀登的每一个单峰的人。不知道如何以这种方式过滤掉其余的人。
最后我的最终查询如下所示:
SELECT PARTICIPATED.NAME, COUNT(DISTINCT CLIMBED.PEAK)
FROM PARTICIPATED
LEFT JOIN CLIMBED
ON CLIMBED.TRIP_ID = PARTICIPATED.TRIP_ID
GROUP BY PARTICIPATED.NAME;
这个查询给出了所有登山者的名字和他们每个人攀登过的山峰总数,但我不知道如何进一步过滤它,以便它只显示在 60 内攀登过 20 多座山峰的人天跨度。 我尝试使用
HAVING CLIMBED.WHEN BETWEEN -60 AND 60;
但这不起作用。
非常感谢任何帮助,我正在使用 Oracle Express 作为我的数据库。
【问题讨论】:
-
你已经发布了这个问题here
-
不是对您的整个问题的回应。但是您的第二个查询应该有
WHERE CLIMBED.PEAK = ALL (... WHERE NAME = 'MARIA') AND NAME <> 'MARIA'。使用IN等价于= ANY(...),但您需要所有的峰,而不仅仅是一个。此外,将 IN 用于单个值是没有意义的,请改用 = 和 。你有一个额外的分号。见this post about ORACLE and ANY, ALL, and SOME。
标签: sql oracle date count oracle-xe