SQL查询-2个查询,涉及COUNT()和所有者';这是一次旅行

SQL查询-2个查询,涉及COUNT()和所有者';这是一次旅行,sql,count,oracle-xe,Sql,Count,Oracle Xe,我的数据库看起来是这样的: 峰值(名称、标高、差异、地图、区域) 攀岩者(姓名、性别) 参与(旅行ID、姓名) 爬升(行程ID、峰值、时间) PEAK提供用户感兴趣的山峰信息。该表列出了每个山峰的名称、海拔(英尺)、难度(1-5比例尺)、所在地图以及所在内华达山脉地区 登山者列出俱乐部的成员,并给出他们的姓名和性别 “参与”给出了参加各种攀登旅行的登山者的集合。每次旅行的参与者人数各不相同 攀爬记录了每次攀爬行程中攀登的山峰,以及每座山峰的攀登数据 我需要为以下两个示例场景编写SQL查询的帮

我的数据库看起来是这样的:

峰值(名称、标高、差异、地图、区域)
攀岩者(姓名、性别)
参与(旅行ID、姓名)
爬升(行程ID、峰值、时间)

  • PEAK提供用户感兴趣的山峰信息。该表列出了每个山峰的名称、海拔(英尺)、难度(1-5比例尺)、所在地图以及所在内华达山脉地区
  • 登山者列出俱乐部的成员,并给出他们的姓名和性别
  • “参与”给出了参加各种攀登旅行的登山者的集合。每次旅行的参与者人数各不相同
  • 攀爬记录了每次攀爬行程中攀登的山峰,以及每座山峰的攀登数据
我需要为以下两个示例场景编写SQL查询的帮助:

  • 马克和玛丽攀登过哪些山峰
  • 在哪些行程中,所有参与者获得的总海拔超过500000英尺
这是我对第一个查询的了解:

SELECT PEAK
FROM CLIMBED
WHERE TRIP_ID IN
    (SELECT TRIP_ID
     FROM PARTICIPATED
     WHERE NAME IN ('MARK','MARY')
     GROUP BY TRIP_ID
     HAVING COUNT(*) = 2
    );
这个问题是,它只给了我马克和玛丽在同一次旅行中攀登的所有山峰。我需要以某种方式得到他们两人都攀登过的山峰,但他们并没有在一起


对于第二个问题,我不知道如何获得所有参与者在特定行程中攀登的每个山峰的计数()。

对于第一个问题,您应该能够删除Having子句,以获得Mark或Mary参与的攀登

    This is for your first query :

    Select c.NAME 
    from PARTICIPATED a
    // join with Climbed to get only peak based trips
    inner join CLIMBED b
    on a.TRIP_ID=b.TRIP_ID
    // join with peak to ge the name of peak
    inner join PEAK c
    on c.NAME=b.PEAK
    // on the result set, filter the results for specific persons only 
    where a.Name in ('Mary','Mark')
SELECT PEAK
FROM CLIMBED
WHERE TRIP_ID IN
    (SELECT TRIP_ID
     FROM PARTICIPATED
     WHERE NAME IN ('MARK','MARY')
     GROUP BY TRIP_ID
    );
保留Having子句意味着您需要Mark和Mary都在特定行程的参与表中,以便trip_id为您提供Having子句规定的2行

要获取其中一个爬过的峰值,而不是另一个,请使用原始查询,但将having子句更改为1:

SELECT PEAK
FROM CLIMBED
WHERE TRIP_ID IN
    (SELECT TRIP_ID
     FROM PARTICIPATED
     WHERE NAME IN ('MARK','MARY')
     GROUP BY TRIP_ID
     HAVING COUNT(*) = 1
    );
这是因为给定where条件,Count(*)将为:

  • 如果其中有一行爬升,则为0(假设-where条件不允许显示此行)
  • 如果其中一人爬上了
  • 如果他们两个都爬了
have子句限制基于分组后的条件的查询,因此通常基于Count(*)之类的聚合,这将为您提供每个分组中“包含”的记录数

第二个问题有点难,但如果我理解正确,您应该能够使用以下内容:

SELECT climbed.trip_id, sum(peak.elev) 
FROM climbed LEFT JOIN participated ON climbed.trip_id = participated.trip_id
LEFT JOIN peak ON climbed.peak = peak.name
GROUP BY climbed.trip_id
HAVING sum(peak.elev) > 500000;
这是因为使用左连接时,每个攀岩者的高程都是复制的;然后,当你为每次旅行求和时,它会为每个登山者加上海拔高度

马克和玛丽攀登过哪些山峰

在不同的行程中:

SELECT c.peak
FROM climbed c
JOIN participated p
   ON c.trip_id = p.trip_id
WHERE p.name IN('mark','mary')
所有参与者在哪些行程中获得的总海拔 超过50万英尺


第一个问题给出了马克或玛丽攀登过的所有山峰。但是有没有办法只显示马克和玛丽都攀登过的山峰,包括他们在不同旅程中攀登过的类似山峰呢。谢谢大家!@Scott让我知道我所做的修复是否对你有效。是的,这是有意义的,我在寻找一些不同的调整,但你的方式更适合我试图实现的。你试图实现一个独家or,对于第一个查询,我想说的是,我需要能够抓取马克和玛丽攀登过的所有山峰,不包括马克攀登过的和玛丽没有攀登过的山峰,或者玛丽攀登过的和马克没有攀登过的山峰。
SELECT c.trip_id, SUM(pe.elev)
FROM climbed c
JOIN peak pe
   ON c.peak = pe.name
JOIN participated pa
   ON c.trip_id = pa.trip_id
GROUP BY c.trip_id
HAVING SUM(pe.elev) > 500000