2012-08-12 109 views
2

我一直對SQLZoo的一個問題感興趣。這是「每組最大的」問題。我想了解引擎是如何運作的。mySQL:這是一種遞歸(或相互依賴)的形式嗎?

名爲BBC的表包含名稱,世界地區和每個國家的人口:

BBC(姓名,地區,人口)

給定的任務是選擇每個人口最多的國家顯示其名稱,地區和人口。

提供的解決方案是:

SELECT region, name, population FROM bbc x 
    WHERE population >= ALL 
    (SELECT population FROM bbc y 
     WHERE y.region=x.region 
      AND population>0) 

1.主要問題。我覺得這有點讓人費解。我想了解引擎如何處理這個問題,因爲初看起來似乎存在某種相互依賴關係(x取決於y,y取決於x)。引擎是否遵循某種遞歸來產生最終選擇?或者我錯過了某些東西,例如x或y實際上是固定的?

2.繼發性問題。奇怪的是,當我從括號內拉出「AND總體> 0」並將其置於底部時,8個結果中有一個區域(歐洲/俄羅斯)缺失。爲什麼?我不明白這一點。

事實上,當我嘗試(可從同一頁的Sakila上的MySQL網站)的世界數據庫查詢,該行爲是不同的: 隨着人口> 0了括號的,我得到6區域。六是在這個數據庫中是正確的數字,因爲「選擇大陸從國家GROUP BY大陸」顯示七大洲,其中一個是南極洲,其中包括5個「國家」,都是0人口。

所以這似乎是正確的。

SELECT continent, `name`, population FROM country X 
WHERE population >= ALL 
(SELECT population FROM country Y 
WHERE Y.`Continent` = X.`Continent`) 
AND population>0 

在另一方面,當我拉「人口> 0」回括號內爲上SQLZoo,我還獲得5個國家以零(國「屬於南極人」)。如果我指定x.population或y.population,則無關緊要,我會得到零。

continent  name           population 
------------- -------------------------------------------- ------------ 
Antarctica  Antarctica            0 
Antarctica  French Southern territories        0 
Oceania  Australia           18886000 
South America Brazil           170115000 
Antarctica  Bouvet Island           0 
Asia   China           1277558000 
Antarctica  Heard Island and McDonald Islands      0 
Africa   Nigeria           111506000 
Europe   Russian Federation        146934000 
Antarctica  South Georgia and the South Sandwich Islands    0 
North America United States         278357000 

非常期待這些問題的見解!

祝大家美好的一週。

:)

注:

  1. 作爲參考,但問題是這個頁面上數3A: http://old.sqlzoo.net/1a.htm?answer=1

  2. 線程提的是「最偉大的正每組「問題的相同查詢: MySQL world database Trying to avoid subquery

  3. 世界數據庫可以在這裏找到:http://dev.mysql.com/doc/index-other.html

+0

(關於第二個問題)如果用'AND population IS NOT NULL'替換AND AND> population> 0,會發生什麼? – 2012-08-12 23:29:23

+0

@ypercube,謝謝。是的,這已經超出了我的想法,並且我嘗試了「並非ISNULL(人口)」。對於SQLZoo查詢,同樣的問題(結果集忽略了歐洲/俄羅斯)。對於「世界」數據庫,同樣的問題(在括號內,我們得到零)。 – zx81 2012-08-13 00:23:13

+0

我打算在圓括號內的SQLzoo查詢中嘗試它。 – 2012-08-13 00:25:57

回答

1
  1. 主要問題。我覺得這有點令人費解。我想了解引擎如何處理這個問題,因爲起初 看起來似乎存在某種相關性(x取決於y, 和y取決於x)。引擎是否遵循某種遞歸 來產生最終選擇?或者我錯過了一些東西,例如 x或y實際上是固定的?

這不是遞歸。見this from the MySQL docs。他們對這個問題的解決方案是相當於這個

SELECT region, name, population FROM bbc x 
    WHERE population = 
    (SELECT max(population) FROM bbc y 
     WHERE y.region=x.region 
     ) 
  1. 次要問題。奇怪的是,當我從括號中拉出「AND population> 0」並將其置於底部時,從8個結果中可以看出 個區域(歐洲/俄羅斯)中的一個缺失。爲什麼?我 不明白。

(用如上述ypercube建議)的微小變化工作

SELECT region, name, population FROM bbc x 
    WHERE population >= ALL 
    (SELECT population FROM bbc y 
     WHERE y.region=x.region 
      AND population IS NOT NULL) 

這個查詢

SELECT region, name, population FROM bbc x 
    WHERE population is null 

返回一行。不知道爲什麼人口應該是空的,但沒有仔細看看其餘部分。否則,查詢應該可以正常工作,而不需要>0

此外,這與每個組的最大值不同。在這個問題中,你試圖找到前N個項目,而不是最上面的項目。

+0

它不完全等同於MAX版本。如果那裏有空位,則不是。 MAX()忽略空值。 'ALL'不。 – 2012-08-13 00:27:22

+0

@dfb,謝謝。 1.關於你的第一點,謝謝,但我的問題不是ALL語法。這是關於引擎如何處理這兩種看起來相互依賴的選擇。 2.關於第二點,可悲的是,不,ypercube提出的修改不起作用 - 問題是如果從括號中拉出「AND population IS NOT NULL」,會發生什麼情況。我們再一次錯過了俄羅斯/歐洲的一排。 – zx81 2012-08-13 00:29:24

+0

@playful - 我上面發佈的版本確實如此,我試過了。問題是,對於所有人口> 0,空值返回FALSE。重新1)解釋你的意思是'引擎如何處理'我不清楚 – dfb 2012-08-13 00:36:45