2016-04-04 127 views
0

我的数据库看起来像这样的业主:SQL查询 - 2个查询涉及COUNT()和一定的行程

PEAK(NAME,ELEV,DIFF,MAP,区)
CLIMBER(NAME, SEX)
参加(TRIP_ID,NAME)
攀升(TRIP_ID,PEAK,WHEN)

  • PEAK提供用户感兴趣的山峰信息。表中列出了每个峰的名称,高程(以英尺为单位),其难度级别(1-5级),地图位于,它位于内华达山脉的地区。
  • CLIMBER列出了俱乐部的成员,并给出了他们的名字和性别。
  • PARTICIPATED给予参加各种攀岩旅行的登山者。每次旅行的参与者人数各不相同。
  • CLIMBED说明每次攀登旅程中攀登哪个高峰,以及攀登每个高峰的数据。

我需要帮助瓦特/写这两个示例场景的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()。

+0

对于我的意思是具体地说,我需要能够抓住所有的峰的,要么马克和玛丽已经爬上不包括那些要么马克攀升和玛丽并没有第一次查询或者玛丽爬了马克没有。 – Scott

回答

1

对于第一个问题,您应该能够删除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子句意味着你需要两个马克和玛丽是在参加表的某一行的trip_id给你2行通过having子句规定。

要获得其中一个已经登上了高峰,而不是其他,使用原来的查询,但改变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如果nither他们的攀升(假想 - WHERE条件不会允许该行显示)
  • 1,如果它们中的一个爬上
  • 2如果他们两个爬上

HAVING子句限制基于分组后条件的查询,所以通常是基于像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; 

这工作,因为使用左连接,每个登山者在海拔被复制;那么当你为每次旅行计算总和时,它会为每个登山者添加高程。

+0

第一个查询给我所有马克或玛丽爬过的山顶。但是有没有办法只显示马克和玛丽都爬过的山峰,包括他们在不同旅途中攀登的相似山峰。 – Scott

+0

第二个查询完全按照预期的方式工作。谢谢! – Scott

+0

@Scott让我知道我做的修复是否适合你。 – Kateract

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

Mark和Mary攀登了哪些高峰?

在不同的旅行:

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

在其车次做所有参与者所获得的总高度 超过500000英尺?

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