2013-02-21 20 views
0

這個問題有點跟隨my previous one。它也基於SQLZOO's "SELECT within SELECT tutorial"。這次是關於任務#8僅用JOIN替換相關的子查詢?

首先,可接受的解決方案:

SELECT w1.name, w1.continent FROM world w1 
WHERE w1.population > ALL(
SELECT w2.population*3 FROM world w2 
WHERE w2.continent=w1.continent and w2.name<>w1.name) 

這一次的相關查詢是在邏輯根深蒂固。

此查詢仍然可以合理地只用JOIN重寫嗎?它應該是?

回答

1

對於此特定查詢,您需要每個大洲的最大和次大值。我將與窗口函數處理這個:

select w.continent, 
     max(case when seqnum = 1 then w.name end) as name 
from (select w.*, 
      row_number() over (partition by continent order by population desc) as seqnum 
     from world w 
    ) w 
where seqnum in (1, 2) 
group by continent 
having max(case when seqnum = 1 then population end) > 3*max(case when seqnum = 2 then population end) 

好吧,我承認,這可能是一個有點先進的,考慮到問題的根源。

所以,這裏是一個方法,你可以把它用做連接,而不是相關子查詢:

我認爲下面就你的邏輯:

select w.name, w.continent 
from world w join 
    (SELECT w.continent, maxpopulation, 
      max(case when population <> maxpopulation then population end) as secondmax 
     FROM world w join 
      (select continent, max(population) as maxpopulation 
      from world 
      group by continent 
      ) c 
      on w.continent = c.continent 
     group by w.continent, maxpopulation 
    ) wc 
    on w.continent = wc.continent and w.population = maxpopulation 
where population >= 3*secondmax 

因此,答案是「是的,你可以做這個沒有相關的子查詢。「在大多數情況下,您可以使用連接和分組來重寫相關的子查詢。

+0

我相信你可能誤解了任務。你是否遵循了我提供的SQLZOO鏈接? – 2013-02-21 17:45:41

+0

作爲一個說明。 。 。自評論以來,我已經完全重寫了答案。 – 2013-02-21 19:23:55

+0

非常感謝。很有意思。 您的第一個查詢按預期工作。然而,甲骨文抱怨第二個。我無法找到解決辦法。 當你有一刻可以重新訪問它嗎? – 2013-02-21 21:25:56

2

因此,任務8說:有些國家的人口是其鄰居(在同一大陸)的三倍以上。給國家和大陸。

我覺得有點不清楚。哪些是鄰居?這是非洲大陸上的所有國家嗎?如果是,那麼接下來的問題是,如果我們比較最小的鄰居還是最大的鄰居。假設它是最大的鄰居。然後查詢將是這樣的

select name, continent 
    from world w1 
where w1.population > (select max(3*w2.population) 
          from world w2 
         where w2.continent = w1.continent 
          and w2.name  <> w1.name) 

否則,如果這將是所有鄰居的3倍在一起會是這樣

select name, continent 
    from world w1 
where w1.population > (select 3*sum(w2.population) 
          from world w2 
         where w2.continent = w1.continent 
          and w2.name  <> w1.name) 

希望它能幫助。

編輯:甲骨文SQL手冊(E26088-01)說,所有功能:

在列表進行比較的值,以每個值或查詢返回。

實施例:

SELECT * FROM employees 
WHERE salary >= 
ALL (1400, 3000) 
ORDER BY employee_id; 

隨着聚合第一和然後比較我們將其降低到一個比較。給定示例表中的結果是相同的。但是針對所有國家的查詢實際上可能會給出不同的結果。所以畢竟我必須說你的查詢更好。如果你在一個大陸有一個人口爲100萬,350萬和1100萬的國家,那麼實際上第二個國家是第一個國家的3倍,第三個國家是第二個國家的3倍。我的查詢只會比較第二個國家和第三個國家,但您的查詢也會比較第一個國家和第二個國家。

+0

這是第一種情況:至少比同一大陸所有其他**個人**國家多3倍的國家。 您是否認爲您的查詢比我的更好(即更高效)? – 2013-02-21 17:58:52

+0

可能效率稍微高一點。我將編輯帖子以澄清這一點。 – hol 2013-02-21 18:03:41