1

この質問は、以前の質問のフォローアップです。また、SQLZOO の「SELECT within SELECT チュートリアル」に基づいています。今回はTask#8についてです。

まず、許容できる解決策:

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 のみで合理的に書き直すことができますか? それはすべきですか?

4

2 に答える 2

2

したがって、タスク8は次のように述べています。一部の国では、(同じ大陸にある)近隣諸国の3倍以上の人口があります。国と大陸を与えます。

少し不明瞭だと思います。隣人は誰ですか?これは大陸のすべての国ですか?はいの場合、次の質問は、最小のネイバーまたは最大のネイバーと比較するかどうかです。それが最大の隣人だとしましょう。その場合、クエリは次のようになります

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)

それが役に立てば幸い。

編集:Oracle SQLマニュアル(E26088-01)には、すべての関数について記載されています。

値をリスト内のすべての値と比較するか、クエリによって返されます。

例:

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

最初に集計してから比較することで、1つの比較に減らします。与えられたサンプルテーブルの結果は同じです。しかし、すべての国に対するクエリは、実際には異なる結果をもたらす可能性があります。結局のところ、私はあなたの質問がより良いと言わなければなりません。人口が1mio、3.5 mio、11 mioの大陸にいる場合、実際には2番目の国は最初の国の3倍であり、3番目の国は2番目の国の3倍です。私のクエリは2番目の国と3番目の国のみを比較しますが、クエリは1番目の国と2番目の国も比較します。

于 2013-02-21T17:51:20.350 に答える
1

この特定のクエリでは、各大陸の最大値と 2 番目に大きい値が必要です。ウィンドウ関数を使用してこれにアプローチします。

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

したがって、答えは「はい、相関サブクエリなしでこれを行うことができます」です。ほとんどの場合、結合とグループ化を使用して相関サブクエリを書き直すことができます。

于 2013-02-21T17:37:03.840 に答える