SQL 查询 - 2 个查询涉及 COUNT() 和特定行程的所有者

SQL Query - 2 queries involving COUNT() and the owner's of a certain trip

我的数据库是这样的:

峰值(名称、海拔、差异、地图、地区)
登山者(姓名、性别)
参与(TRIP_ID,姓名)
攀升(TRIP_ID,高峰,时间)

我需要帮助编写针对以下 2 个示例场景的 SQL 查询:

这是我的第一个查询:

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
    );

这个查询的问题是它只提供了 Mark 和 Mary 在他们一起进行的同一次旅行中攀登的所有山峰。我需要以某种方式获得他们都曾攀登过的山峰,但他们并没有在一起。

对于第二个查询,我不知道如何获取所有参与者在特定 TRIP_ID 期间攀登的每个山峰的 COUNT()。

    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')

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

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 都在 Participated table 中参加特定行程,以便 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 条件不允许显示此行)
  • 1 如果其中一个攀登
  • 2 如果他们都爬了

Having 子句根据分组后的条件限制查询,因此通常基于像 Count(*) 这样的聚合,它会给出每个分组中 "contained" 的记录数。

第二个问题有点难,但如果我理解正确的话你应该可以这样使用:

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;

这是有效的,因为使用左连接,每个登山者的海拔高度被复制;然后当你对每次旅行求和时,它会添加每个登山者的海拔。

Which peaks have been climbed by Mark and Mary?

在不同的行程中:

SELECT c.peak
FROM climbed c
JOIN participated p
   ON c.trip_id = p.trip_id
WHERE p.name IN('mark','mary')

On which trips did the total elevation gained by all participants exceed 500,000 feet?

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