サブクエリは、SQLクエリに表現力を追加しますか?


29

SQLにはサブクエリが必要ですか?

関係データベース用の構造化照会言語の十分に一般化された実装を想像してください。正規のSQL SELECTステートメントの構造は、これが意味をなすために実際に非常に重要なので、リレーショナル代数に直接アピールしませんが、式の形式に適切な制限を加えることで、これらの用語でこれを組み立てることができます。

SQLのSELECTクエリは、一般的に投影(から成るSELECT部分)のいくつかの数JOINの操作(JOINパート)、いくつかの数SELECTION の操作(SQLにおいて、WHERE句)、セット単位(操作UNIONEXCEPTINTERSECT、など)、他の続きますSQL SELECTクエリ。

結合されるテーブルは、式の計算結果にすることができます。言い換えると、次のようなステートメントを作成できます。

SELECT t1.name, t2.address
  FROM table1 AS t1 
  JOIN (SELECT id, address 
          FROM table2 AS t3 
         WHERE t3.id = t1.id) AS t2
 WHERE t1.salary > 50,000;

SQLクエリの一部として計算テーブルをサブクエリとして使用することに言及します。上記の例では、2番目の(インデントされた)SELECTサブクエリです。

すべてのSQLクエリは、サブクエリを使用しないように記述できますか?上記の例は次のことができます。

SELECT t1.name, t2.address
  FROM table1 AS t1 
  JOIN table2 AS t2
    ON t1.id = t2.id
 WHERE t1.salary > 50,000;

この例はやや見せかけの、または取るに足らないものですが、同等の式を回復するためにかなり多くの労力が必要になる場合が考えられます。言い換えると、サブクエリを含むすべてのSQLクエリ、サブクエリないクエリq が存在し、qおよびq が同じ基になるテーブルに対して同じ結果を生成することが保証されている場合ですか?SQLクエリを次の形式に制限しましょう。qqqq

SELECT <attribute>,
      ...,
      <attribute>
 FROM <a table, not a subquery>
 JOIN <a table, not a subquery>
  ...
 JOIN <a table, not a subquery>
WHERE <condition>
  AND <condition>
  ...
  AND <condition>

UNION
 -or-
EXCEPT
 -or-
<similar>

SELECT ...

等々。左と右の外部結合はあまり追加されないと思いますが、私が間違っている場合は、それを指摘してください...いずれにしても、それらは公正なゲームです。集合演算に関する限り、それらのいずれもうまくいくと思います...結合、差、対称差、交差など、役立つものは何でも。すべてのSQLクエリを削減できる既知の形式はありますか?これらのいずれかがサブクエリを排除しますか?または、サブクエリのない同等のクエリが存在しない場合がありますか?参照は高く評価されます...または、それらが必要であるか不要であるかの証明(証拠による)は素晴らしいでしょう。感謝します。これが有名な(または些細な)結果であり、申し訳ありませんが、その結果、私は痛いほど無知です。


5
私の腸は、集約された値を必要としない限り、いつでもすべてを結合してそこから選択できることを教えてくれます。列の平均より大きい値を持つすべてのエントリを選択するには、最初にavergeを計算する必要があるため、サブクエリが必要です。
ラファエル

@Raphael集約された値を実行することもできると確信しています。もっと多くの自己結合とグループ化を行う必要があります(指数関数的に大きくなりますが、それでも可能です)。しかし、そのようにすべてを行うことができることを正式に証明する方法がわかりません。
ケビン

@Kevin必要な操作の数は行の数に依存していませんか?持ってないからね
ラファエル

1
サブクエリを要求するために私が持っている通常の例は、重複のカウントです:select count(*) from (select id from sometable group by id having count(*)>1) d。それが含まれgroup byているので、私はこれを答えとして入れていません。
マークハード

ところで、通常のSQLではsにONは句が必要ですがJOIN、カンマだけで外積が取得されます。
マークハード

回答:


9

いくつかの用語の混乱があります。括弧内のクエリブロック

SELECT t1.name, t2.address
  FROM table1 
  JOIN (SELECT id, address 
          FROM table2 AS t3 
         WHERE t3.id = t1.id) 

内部ビューと呼ばれますサブクエリは、例えばいずれか、またはSELECT句内の問合せブロックであり、

select deptno from dept
where 3 < (select count(1) from emp 
           where dept.deptno=emp.deptno)

どちらの場合でも、内部ビューまたはサブクエリをネストして、「フラットな」プロジェクト制限結合にネストできます。集約された相関サブクエリは、グループ化により内部ビューにネスト解除され、その後、フラットクエリにネスト解除されます。

select deptno from dept d
    where 3 < (select avg(sal) from emp e
               where d.deptno=e.deptno)

select d.deptno from dept d, ( 
    select deptno from emp e
    group by deptno
    having avg(sal) > 3
) where d.deptno=e.deptno

select d.deptno from dept d, emp e
where d.deptno=e.deptno 
group by d.deptno
having avg(sal) > 3

クエリの最適化のための代数的ルールとして、リレーショナル代数をaxiomatizedにされることが知られているリレーショナル・ラティス実証されるように、クエリの変換を簡素化し、ここそこ


気になります。平均値を超えるすべてのエントリを選択するなど、一部のフィールドの平均値を使用するクエリの例を追加できますか?平坦化した後、どのように見えるかは明確ではありません。
ラファエル

16

あなたの声明をリレーショナル代数に翻訳するには、私はそれが尋ねると思う:

σA(A)σB(B)σA(σB(AB))

σ

答えは「はい」であり、これは標準のクエリ最適化です。正直に言うと、私はこれを疑いの余地のない方法で証明する方法がわからない-それは単なる選択と参加の特性だ。必要に応じてネストされたクエリの多くの層を追加するように帰納的に主張することができます。

さらに、あなたは尋ねるかもしれません:

ABC(AB)(CD)

結合は結合的であるため、答えはイエスです。投影についても同様のステートメントを作成できます。

「フラット化」できないと思う「サブクエリ」の注目すべきタイプの1つはwithです。これを確認する1つの方法は、withステートメントがある場合、サブクエリを使用せずに記述できない再帰関数を使用できることに注意することです。

つまり、あなたが言及した特定のケースでは、いいえ、SQLはサブクエリを必要とせず、帰納的に証明できます。ただし一般的には、サブクエリを必要とする機能があります。


経由の再帰的動作withはSQL:1999で導入され、結果の言語を厳密に表現力豊かにします。
アンドラスサラモン

1

「サブクエリはSQLクエリに表現力を追加しますか?」

少なくとも、SQL言語でEXCEPTが導入される前は、そうでした。

EXCEPTが導入される前は、サブクエリに頼らずにSQLで関係の相違または半相違を表現する方法はありませんでした。

最近では、「the」関係代数の「典型的な」プリミティブ演算子はすべて、サブクエリなしで表現できます。

NATURAL JOINはNATURAL JOINを通じて、またはJOIN ON
UNIONはUNION
MINUS を通じて行うことができます。EXCEPTPROJECT
/ RENAME / EXTEND
を通じて
行う
ことができます。再帰的なWITHを介して行われます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.