2016-04-04 118 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