SQLがすごい便利に感じた話

こんにちは。 
今回記事を書かせていただきました、**渡辺**です。
 
今回の記事はSQLに着目した内容になっております。 普段の業務をこなしていく上で、いわゆる「できる人」のSQLを見た時に、
<font color="#ff0000">**これが自分でも使えたらすごい便利じゃん！**</font>
とSQLに可能性を感じたため、今回はSQLについて取り上げることにしました。
初心者なりにまとめた内容になりますので、その辺ご留意いただけると幸いです、、
 
以下、目次になります。
**1、SQLってなに？ **
**2、SQLが便利に感じた理由 **
**3、主に業務で使ったコマンドについて **
**4、まとめと今後の展望**


## 1、SQLってなに？
SQLは「Structured Query Language」の略称で通称「エスキューエル」です。(「シーケル」、「シークェル」と呼ばれることもあります)
SQLはデータベース言語であり、DBMS(データベース管理システム)にユーザーが求める処理を命令するための宣言型言語です。 具体例をあげるなら、お店でご飯を食べるまでの一連の流れの「**注文**」部分にあたります。
(お店に行く→**料理を注文する**→待つ→料理が届く→食べる)

 SQLでデータベースを操作する方法としては、 「対話型」と「埋め込み型」の2種類があります。 
 「対話型」はデータベースへ命令を送る、データベースからデータを受け取るの流れを繰り返す形式でキャッチボールのような感じです。 
 また「埋め込み型」はソースの中にSQLを埋め込んで、システムを動かす時に合わせて操作する形式です。
 私の業務ではどちらも同じくらいの重要度で、 「対話型」は<font color="#ff0000">**ソースのデバッグやテスト**</font>に、「埋込み型」は<font color="#ff0000">**ソースの製造**</font>をしていく上でかなり重宝しました。

## 2、SQLが便利に感じた理由 
「製造の選択肢が広がり、効率化できる」ことです。 
選択肢が広がるのはSQLに限った話ではないかもしれませんが、SQLはデータベースと深い関係があり、データベースはITの仕事をしていく上で必ず利用するものといっても過言でないため、活用できる範囲が非常に広いと思います。
効率化に関しては実際の業務で、1000行以上書いていたソースがSQL側で条件の一部を担うことで、 約700行まで減少したことがありました。(加えてビジネスロジックの煩雑な関数が一つでまとめられ、視認性も保守性も良くなりました) 

特に「**サブクエリ(インラインビュー)**」を用い、複雑なテーブル結合を行わずに済んだことでSQL自体もそこまで複雑になりませんでした。  
このようにSQLをうまく活用することでビジネスロジックの簡略化を行い、かつSQL自体も難しくないというwin-winな関係が出来上がります。 

もちろんソースの最適化・効率化をする際、SQLとビジネスロジックどちらで対応すべきかどうかは**ケースバイケース**になります。
ですが、「SQLでも対応できる力」を持つことで処理が効率化できる状況は非常に多くあると思います。

## ３，主に業務で使ったコマンドについて
ここからは具体的にどのようなコマンドを使用したかご紹介します。
ほとんど基本的なものですが、備忘録として記載しております。

###  3.1 CREATE    

言わずと知れた超基本のコマンドです。     
CREATEはデータ登録や更新、削除のテストを
行うためテンポラリーテーブル(一時的なテー
ブル)や、またはview(ビュー)と呼ばれる仮
想テーブルを作成するために使用しました。

CREATE 具体例     
```
CREATE TABLE test_table(   
  id      INT(7),   
  name    VARCHAR(50),   
  address VARCHAR(50),   
  age     INT(3),    
  code    VARCHAR(50),   
  type    VARCHAR(10)     
);       
```

CREATEでid、name、address、code、typeカラムを持つテーブルを作成しています。        

### 3.2 SELECT(COALESCE, CASE, WHERE, LIKE)       
SELECTは特定の条件のデータを取得するため、主にWHERE句やCASEなど(後述)と合わせて使用しました。   

SELECT 具体例  
```
SELECT       
  t1.id,               
  COALESCE(t1.name,'aaa'),         
  t1.age,    
  CASE t1.code      
  WHEN 1 THEN 'A'      
  WHEN 2 THEN 'B'      
  WHEN 3 THEN 'C'       
  ELSE 'D'     
END AS rank   
FROM test_table t1   
WHERE t1.type = 'red'    
  AND t1.address LIKE 'tokyo%'  
```
  
SELECTで「test_table」からid、name、rankを取得しています。  
COALESCEを用いることで取得したname要素がnullだった場合に'aaa'に置き換えるようにできます。    
またrankはCASEを用いて各レコードのcodeの値によって変化する値が代入されています。    
最後のWHEREにて各レコードの持つtypeの要素が「red」のものかつ、address要素が「tokyo」から始まるもののみ取得するようにしています。 

### 3.3 サブクエリ(インラインビュー)   
複数のselectを用いて、仮テーブルを作成し複雑な問い合わせを簡潔に行うために使用しました。  
ビジネスロジックにて条件分けを行っていた内容をSQL側のサブクエリで対応することで、効率よく処理することができる場合があります。   
サブクエリ 具体例     
```
SELECT      
  iv_1.id,     
  CASE       
    WHEN iv_1.age > 20 then      iv_1.name 
  ELSE null   
  END AS name    
  iv_1.address,     
  iv_1.code,    
  CASE iv_1.code      
    WHEN 1 THEN 'A'     
    WHEN 2 THEN 'B'     
    WHEN 3 THEN 'C'     
    ELSE 'D'   
  END AS rank      
  FROM (
    SELECT       
      t1.id,       
      t1.age,       
      COALESCE(t1.name,'aaa'),   
     COALESCE(t1.address,'japan'), 
     COALESCE(t1.code,4),      
     FROM test_table t1       
     WHERE t1.type = 'red'     
       AND address LIKE 'tokyo%'  
     ) iv_1                
```
サブクエリを用いることで取得する要素に複数のふるいをかけることができます。
今回の例では、仮想テーブルを作成し、そのテーブルで取得した要素をさらに条件分けしています。    
仮想テーブル内ではCOALESCEでnullだった場合に指定した要素を代入し、 その要素を用いてCASEを用いた条件分けを行っています。

他にも、LEFT JOINやEXISTSなども使用した場合もありました。(今回は紹介を省きます)

　ここまででいくつかコマンドをご紹介しましたが、今の私の業務で触れるSQLは基本的に上記したコマンドで構成されており、難しすぎる！！と感じるSQLは**あまりなかった印象**でした。

## ４，まとめと今後の展望
今回はSQLについてまとめました。
ほとんど備忘録のような内容になっていますが、今の私の現場では紹介したコマンドについて理解していれば
ある程度戦えるはずなので、もっと勉強したいなと感じ始めました。
もともとSQLには苦手意識があり避けてきたのですが、だんだんSQLと触れる機会が増えていき、
SQLの有用さと可能性に気付いたことでモチベーションもふつふつと湧いてきています。
 
現場の先輩曰く、「SQLはかなり難解な分野ではあるが極めれば活躍の場所が一気に増える」と伺ったので、いま勉強している資格を取り終わったら少しずつSQLの勉強も始めたいと思います。
 
ここまでお読みいただきありがとうございました。
また機会があれば記事をおこそうと思います。
それでは！
 
 
P.S.  
何か製造するときは仕様について99%は理解してから始めましょう！
手戻りが一番心に来るので！！！(体験済)


##### 参考
https://hnavi.co.jp/knowledge/blog/sql/