SQLで出てくる「句」という言葉の意味がよくわかっていなかった。
なので、SQLにおける文、句、式の違いについて調べてみたら、思いがけずに面白かったので書いておきます。
目次
SQLの句ってどういう意味? プログラミング言語には出てこないけど……
まず、SQLにおける「句」とは、どういう意味なのか結論を書きます。
句:特定のキーワードと表名、列名、式などが結びつき、特定の働きをする部分
(引用元:オラクルマスター教科書 Bronze)
これだけの意味なんですよね。
もう少しプログラムっぽく表現すると、
句: 句 + 条件(予約語、識別子、演算子、定数、式)でまとまった処理を表す
と言えます。
(識別子は、表名、列名などのデータベースオブジェクトを識別するための名前です)
以後は、データベースエンジニアでない私が調べたこと、SQLの「句」がわかりにくかった原因や面白いなと思ったことを備忘録として、書いていきます。
(間違った解釈を書いていたら、すいません)
対象読者としては、
一般的な(手続き型)プログラミング言語の文法用語はなんとなく知っていて、
SQLもなんとなく書けるけど、
SQLの文法用語(特に句)の意味がよくわからないなと思っている人向けの内容になります。
SQLのことについてだけでなく、プログラミング言語についてのことと交えて書いていますので、SQL構文の正確な定義が知りたい人向けではなく、SQLに困らない程度に意味・役割がわかればいいやという人向けです。
とりあえず、SQLを扱う上で、SQL読解したり、人と会話したり、ドキュメントを読む際に混乱しないくらいにはなれると思います。
SQL文の構成要素
SQL文の構成要素について、書いていきます。
参照:https://en.wikipedia.org/wiki/SQL#Syntax
文、句、式の意味を調べると、この図に行き当たるのですが、この図や説明文を読んでも意味がイマイチわかりませんでした。。。
なので、いくつかネット記事や書籍を読んでみて、かみくだいて意味を解釈して、下記のような認識でいます。
式(expression)
式の意味は、1つ以上の値、演算子、および値に評価されるSQLファンクションの組合せです。
参照:https://docs.oracle.com/cd/E16338_01/server.112/b56299/expressions001.htm
式はそれ単独では完結しない要素であり、文または句、式の一部として使用されます。
式の特徴として、値(数値や文字列など)を返します。
(文が(副作用を起こしうる)実行単位なのに対して、式は評価単位です)
SQLの場合は、テーブルを値として扱っています。
SQLだと、CASE式という言葉をよく聞きますが、「値を返すものなら何でも式でしょ」くらいの認識でいます。
述語(predicates)
述語の意味は「条件式の別名」です。(条件式は、真偽値、不定値を返す式のこと)
参照: http://www.ie.reitaku-u.ac.jp/~tak/rdb2/rdb2-04.pdf
この言葉は、なんかカッコイイ呼び方をしているくらいの認識でいます。
今のところ、SQL本で述語と出てきたとき、条件式と変換して読んでいて問題を感じたことはないです。
今のところ、SQL本で述語と出てきたとき、条件式と変換して読んでいて問題を感じたことはないです。
WHERE句やHAVING句の後ろに来る条件を探索条件というらしく、
探索条件は、1つ以上の述語(条件式)を、AND、OR、NOTで組み合せてできた論理式のことです。
つまり、述語とは探索条件を構成する最小単位という意味合いで使われているみたいです。
参照:https://software.fujitsu.com/jp/manual/manualfiles/m170014/j2ul1610/03z201/j1610-00-01-02-00.html
JavaやJavaScriptなどでも、predicateという関数は出てきますし、同じ使われ方ですよね。
(predicateの和訳が「述語」とは知らなかったのですが……)
ググると一番に出てくる記事【用語解説】わかりにくいSQLの句・文・式の違いには、
「大きさでイメージするなら 文 > 句 > 述語 ≧ 式」と書かれているけど、
むしろ「文 > 句 > 式 ≧ 述語」のイメージのように私は解釈しました。。。
句(clause)
句の意味は、 句 + 条件(予約語、識別子、演算子、定数 、式)で特定の働きをします。
参照:Access SQL: 基本的な概念、用語、および構文
SQL文を構成する要素であり、単独では完結しません。
WERER句、BETWEEN句、GROUP BY句などがあります。たくさんあります。
文(statement)
文の意味は、SQLにおける実行単位です。
文はそれ単独で完結する言語要素です。
よく使う代表的な文は、SELECT文、UPDATE文、INSERT文、DELETE文ですね。
「文」は「式」とは違って、値を返しません。
また、たいてい(手続き型)プログラミング言語においては、「文」は手続きを表します。
サブクエリは文なの式なの?
上記の文のうち、SELECTのみはサブクエリとして扱えることからわかるように値を返せていますが……これはどういうことなんだろうと思いました。
「サブクエリ式」という単語でネット検索すると、わずかにヒットします。
サブクエリは式として捉えられるんだなということがわかります。
SELECT句+条件 に対して、;(セミコロン)をつければ文として実行され、()で囲めば式(サブクエリ)として評価されるんだろうなと、私は解釈しています。
例えば、Javaだったら、hoge=1は代入文であり、戻り値はなく、代入式としては使いようがありません。
しかし、式と文の区別がない(あいまいな?)プログラミング言語であるRubyは hoge=1 に対しても戻り値を持ちます。
参照:式と文、評価と実行、そして副作用 ―― プログラムはいかにして動くのか【前編】
私のサブクエリのイメージはこんな感じです。
SELECT句 + 条件は、見た目はほぼ変わらない書き方で、文としても式としても使えるんだろうなと。
SQLの句の意味がよくわからなかった原因について
私がSQLにおける「句」という意味がよくわからず混乱していた原因は、2つあったのかなと考えています。
SQLパラダイムにプログラミング言語パラダイムを当てはめようとした
まず、一つ目に、SQLパラダイムに手続き型プログラミング言語パラダイムを当てはめようとしたことが挙げられます。
そのせいで、句の役割の広さをきちんと意識できていなかったと思います。
句は、句 + 条件で特定の働きをするわけですが、その働きは一般的なプログラミング言語における構文要素には当てはまらない広さを持っていると思います。
SQL句の働きのイメージを下記表にしてみます。
SQL句 | 機能 | プログラミング言語 でのイメージ |
---|---|---|
SELECT | 目的のデータが含まれているフィールドを列挙 | get |
WHERE | 各レコードが結果に含めるために満たす必要があるフィールド条件を指定 | if文 |
ORDER BY | 結果の並べ替え方法を指定 | sort関数 |
GROUP BY | 集計関数が含まれている SQL ステートメントで、SELECT 句でグループ化されないフィールドを指定 | なし |
BETWEEN | 範囲比較を指定 | 比較演算子 |
SQLの句の働きを、手続き型プログラミング言語の構文要素で一致するものを無意識に探して、当てはめようとしていたけれど、見つからないからしっくりこなかったのかなと。
言語パラダイムについて全然知らないですが、そもそもSQLは集合論に発する言語であり、手続き型ではなく、宣言型の言語らしいですし、プログラマでない人でも簡単に使えるように自然言語(英語)に似せた構文であるのが特徴な言語らしいです。
句という単位で、様々な役割を果たすのは自然言語っぽく感じますし、GROUP BY句は集合指向(行単位ではなく、集合単位で扱う)ならではの働きなのかなと感じます。
手続き型プログラミング言語は色んな文の種類がありますが、SQLの場合は、基本的なデータ操作に関しては、4つの文だけで行え、その代わりに句の種類が多いのかなと調べていて思いました。
参照:手続き型から宣言型・集合指向に頭を切り替えるための7箇条
SQLの構文規則に従って役割を考えられていなかった
2つめの理由というか、そもそもSQL句の役割はそういうものだという意識が弱かったので、句の役割をSQLの構文の定義に従って考えられていなかったです。
例えば、CASE句の場合、
CASE句 + 条件 = CASE式 というように、句が条件と合わさって、式の役割になることがあるんだということを、わかっていなかったです。
(SQL文を書く上では問題なかったけど、本を読むときに理解できないまま読んでいる状態でしたね)
また、BETWEEN句の場合、
ネットで検索すると、BETWEEN演算子・BETWEEN述語(条件式)という言葉でも出てきますが、句を理解しておらず、BETWEEN句の役割を考えられなかったら、こういった言葉で使われることが自然だという認識は持てていなかったと思います。
結論として、SQLの用語・パラダイムはきちんと調べよう
手続き型のプログラミング言語を少し知っていたから、SQLに似たような用語や役割が出てきたときに、勢いあまってSQLの全てを手続き型のプログラミング言語の考え方に(無意識に)当てはめようとしてしまのが間違いでした。
SQLは、手続き型のプログラミング言語 とは違う発想の元に生まれた、
SQL言語(Structured Query Language = 構造化問い合わせ言語)だという認識を持って、
わからない概念・言葉が出てきたら混乱する前に、ちゃんと調べるのが良いですね。
くもりなき眼と頭で、SQLと考えて使うのが大切ということでした。