プログラミング初心者の勉強ブログ #96
Pythonオンライン学習教材として評判のPyQ(https://pyq.jp/)によるPython学習記録です。Rubyを多少かじり、第二外国語としてPythonを少しづつ学んでいきます。(内容はRubyとの比較が多くなるかもしれません。)
今回はPyQの「はじめてのSQL」で久しぶりにSQLの文法に触れて、曖昧になっていた部分が多々あったので、今度こそ頭に残すべくまとめます。SQLの基本の基本です。
目次
[toc]
「SQL」と「クエリ」
僕が最初にSQLを勉強したとき、すぐ次にRubyのActive Recordを勉強したのもあり何かとごっちゃになってたり、Active Recordに頼りすぎて元のSQLの文法を忘れてたりしてました。今回SQLをまとめるにあたり、まず「SQL」と「クエリ」という言葉の整理をします。
SQLとは
SQLとはデータベースとやり取りするときに使う言葉(のひとつ)です。
データーベースさんとコミュニケーションをするときに使う言葉(のひとつ)が「SQL」です。
SQLのQは「Query(問い合わせ)」であり、Lは「Langage(言語)」です。
クエリとは
クエリ (query)とはデータベースさんに対する「おい!これやれよ」な命令文のこと。あるいは調べ物をするときに検索エンジンさんに入力する検索キーワードのことです。
クエリはデータベースに対する問い合わせであり命令です。
Active RecordはRuby言語でSQLを実行してくれて、実行されたSQLによってクエリが発行され、データベースに命令が届きます。Railsで開発をしているとActive Recordが使えれば問題がないので、逆にSQLを直で書いてみろと言われたら困る訳です。一段階すっ飛ばしてる状態なので「HAVING」とか「IN」とか見ると少し戸惑う現象が起こります。
今回はその戸惑いを解消したいと思います。
SQL文の基本
検索
【原型】SELECT (カラム) FROM (テーブル)
(テーブル)の(カラム)を検索します。
【条件付①】SELECT * FROM (テーブル)WHERE (条件1) AND (条件2)・・・
SELECT * FROM users WHERE id=1
のような形で、演算子などを用いてWHERE後ろに条件を書いていく。ANDでつなげられる。
【条件付②】SELECT * FROM (テーブル)WHERE (カラム) IN (条件)
SELECT * FROM users WHERE id IN (1, 2, 3)
のような形で、指定した(カラム)に複数条件が付けられる。また、
SELECT * FROM users WHERE blog_id IN ( SELECT id FROM blogs WHERE title='aaa')
のような形で、IN内にSELECT文を書くことが可能なので、より複雑なクエリを発行できる。
【条件付③】SELECT * FROM (テーブル)WHERE (カラム) LIKE (条件) OR ・・・
あいまい検索機能を実装したいときなどに使用される。ORでつなげられる。
SELECT * FROM users WHERE name LIKE '%a%' OR name LIKE '%b%'
とすることで、users全体からnameにaかbが入っているものを検索できる。%は「0文字以上の任意の文字列」を表し、「%a%」とすることでaの前後に0文字以上の任意の文字列があるものをすべて拾ってくる。
ちなみに%の代わりに「_」を指定すると「1文字以上の任意の文字列」を表す。
【条件付④】SELECT * FROM (テーブル)WHERE NOT(カラム) LIKE (条件) OR ・・・
【条件付き③】の文章にNOTを指定できる。
【範囲条件】SELECT * FROM (テーブル)WHERE(カラム) BETWEEN (条件A) AND (条件B)
英語のbetweenと一緒の使い方。範囲条件を指定できる。
SELECT * FROM users WHERE id BETWEEN 1 AND 10
とすることでidが1〜10のuserを取得できる。
【グループ化】SELECT (カラム) FROM (テーブル) GROUP BY (カラム)
グループ化を行うことで、指定したカラムを「集合」の概念で扱うことができます。
例えば
SELECT id, name FROM users # --> 1 田中 2 鈴木 3 佐藤 4 田中 5 田中 6 鈴木
のようなusersテーブルがあったとします。田中が多く、3人もいます。
このusersテーブルでnameに対しグループ化を行うと、
SELECT name FROM users GROUP BY name # --> 田中 鈴木 佐藤
このように同じ名字は1つしか表示されなくなります。
SELECT name, COUNT(*) FROM users GROUP BY name # --> 田中 3 鈴木 2 佐藤 1
COUNT( * )はデータ数を取得するSQLの関数です。今回の場合、田中は3人いることがわかるようになります。
【ソート】SELECT * FROM (テーブル) ORDER BY (カラム)
ORDER BYの後ろに指定したカラムの値でソートします。デフォルトはASC(昇順)であり、DESC(降順)にしたい場合は
SELECT * FROM (テーブル) ORDER BY (カラム) DESC
のように後ろに追加する。
【結合】 SELECT(カラム) FROM (テーブル) JOIN (カラム) ON (外部キー =主キー)
JOINはテーブルの結合ができる。書き方が他と比べ少し特殊。Railsのアソシエーションの考え方。
SELECT users.id, users.name, blog.title FROM users JOIN blogs ON users.blog_id=blogs.id
のように書くことでusersテーブルとblogsテーブルを結合させてデータを取得できるようになる。デフォルトは内部結合であり、外部結合にする場合は「LEFT(RIGHT) OUTER JOIN (カラム) ON (条件)」とする必要がある。
関数
関数名 | 内容 |
COUNT() | データ数 |
MAX() | 最大値 |
MIN() | 最小値 |
AVG() | 平均 |
SUM() | 合計 |
先ほど使ったCOUNT含め、基本的な処理はこれらの関数とグループ化を組み合わせて行うことができる。
追加・更新・削除
INSERT INTO テーブル(カラム1, カラム2, …) VALUES(値1, 値1, …)
INSERT INTO users(id, name) VALUES (1, '田中')
テーブルを追加する。
UPDATE (テーブル)SET (カラム1=値1, カラム2=値2, …)WHERE (条件)
UPDATE users SET (name='鈴木') WHERE id=1
テーブルを更新する
DELETE FROM (テーブル) WHERE (条件)
DELETE FROM users WHERE id=1
テーブルを削除する
まとめ
INとかONとかSETとか前置詞がややこしいSQLですが、英語の勉強と違って暗記してなくてもなんとかなるのがプログラミングの良いところだと勝手に思ってます。データベースとか一番興味ないなとか思ってましたが、Webアプリ作る上で知っとかないとどうにもならないときがあるのでSQLはしっかり覚えるようにします。効率をあげたり検索アルゴリズムを充実させるにはテーブル設計の手腕とSQLの知識が結構問われるなと感じ、今後railsのransakなどでもう少しちゃんとした検索機能を作るためにもここで基本をもう一度確認しときたいと思いまとめました。「webアプリ作るのに必要だからSQL知っとかなきゃ」という流れは自分の中で理想的であり、「SQLを学んでおくとwebアプリ作るとき役に立つよ」の流れだと頭にちゃんと入りません。これは僕が計画的な人間でないからなのか、それとも全ての人が当てはまることなのか。プログラミングの勉強し始めてからだんだんとアウトプット至上主義になり始めてます。〇〇至上主義とか書くと、あたかも賢く見え、自分のアイデンティティの一つとして価値観を他者に端的に伝えることができます。これに似たようなジャンルで僕が最近覚えた言葉は「マウントをとる」です。あたかも賢いです。このような言葉はたくさんあります。そして皆それらの言葉からパワーを感じ、素直に使う人もいれば、斜に構える人もいます。なんだかよくわからないパワーを持つこのような言葉は世の中にたくさん転がっており、「あたかも賢い」ジャンルではないですが、僕が前働いていた会社では「サムシングニューな企画」とか「ボディーブローのように効いてくる」とか「ケツカッチン」とか、思い出せないだけで他にも色々聞いてきました。特に何が言いたいわけでもないですが、僕はこういうスタイルでマウントをとっていくキャラでいこうと思ってるということを素直に言えないだけです。この取り組みは僕の中でのサムシングニューであり、こういったサムシングニューを行うのと行わないのでは、後々のブログPV数獲得にボディーブローのように効いてくると思っています。(残念ながら僕は暇人なのでケツはカッチンしないので盛り込めません。)
以上ありがとうございました。