【问题标题】:SQL Query - 2 queries involving COUNT() and the owner's of a certain tripSQL 查询 - 涉及 COUNT() 和某次旅行的所有者的 2 个查询
【发布时间】:2016-07-24 14:16:04
【问题描述】:

我的数据库如下所示:

峰(姓名、海拔高度、差值、地图、地区)
登山者(姓名、性别)
参加(TRIP_ID、姓名)
爬升(TRIP_ID、PEAK、WHEN)

  • PEAK 提供有关用户感兴趣的山峰的信息。该表列出了每个山峰的名称、海拔(以英尺为单位)、难度级别(1-5 级)、地图位于,以及它所在的内华达山脉地区。
  • CLIMBER 列出了俱乐部的成员,并给出了他们的姓名和性别。
  • PARTICIPATED 提供了参加过各种登山旅行的登山者的集合。每次旅行的参与者人数各不相同。
  • CLIMBED 会根据每座山峰的攀登数据,告诉您每次攀登过程中攀登了哪些山峰。

我需要帮助我为这 2 个示例场景编写 SQL 查询:

  • 马克和玛丽攀登了哪些山峰?
  • 所有参与者在哪些行程中获得的总海拔超过 500,000 英尺?

这是我第一个查询的结果:

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

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

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

【问题讨论】:

  • 对于第一个查询,我的意思是说我需要能够抓取 Mark 和 Mary 攀登过的所有山峰,不包括 Mark 攀登过而 Mary 没有攀登过的山峰或者玛丽爬了,而马克没有。

标签: sql count oracle-xe


【解决方案1】:

对于您的第一个问题,您应该能够删除 Have 子句以获取 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 表中,以便trip_id 为您提供have 子句规定的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 如果他们都爬了

有子句根据分组后的条件限制查询,因此通常基于 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;

这是可行的,因为使用左连接,每个登山者的海拔都是重复的;然后,当您对每次行程求和时,它会添加每个登山者的海拔高度。

【讨论】:

  • 第一个查询为我提供了 Mark 或 Mary 攀登过的所有山顶。但是有没有办法只显示马克和玛丽都爬过的山峰,包括他们在不同旅行中爬过的类似山峰。
  • 第二个查询完全按预期工作。谢谢!
  • @Scott 让我知道我所做的修复是否对您有用。
  • 是的,这是有道理的,我有点想寻找一些不同的调整,但你的方式更适合我想要完成的工作。
  • 你正在尝试实现一个异或,它在 SQL 中实际上没有关键字。
【解决方案2】:
    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')

【讨论】:

    【解决方案3】:

    马克和玛丽攀登了哪些山峰?

    在不同的旅行中:

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

    所有参与者在哪些行程中获得的总海拔高度 超过 500,000 英尺?

    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
    

    【讨论】:

      猜你喜欢
      • 2016-07-26
      • 2020-04-05
      • 1970-01-01
      • 2011-01-04
      • 2023-02-21
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      相关资源
      最近更新 更多