SQL部：基本構文の裏技

#はじめに

SQLの基本的な構文とかそういうのをメモ書きするだけです。

#環境

mysql> status
mysql  Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1


#入力の基本的なルール

・コマンドの終端はセミコロン(;)
・コマンドの大文字小文字は問わない。
→**データベース名、テーブル名、カラム名は大文字小文字を区別する**。
・途中で入力を辞めたいときは**¥c**と入力。(Ctrl + Uでも行ける。)

#ログイン

$ mysql -u UserName -pPassword DBName


#mysqlコマンド

**・db1のtable1のカラム一覧を表示させたい時の流れ**
**①ターミナルでmysqlコマンドを実行後show databases;**
これでデータベース一覧を表示させる。

**②use db1;コマンドを打つ**
useで作業データベースを指定する。この場合はdb1を指定する。

**③show tables;コマンドを打つ**
これによってテーブル一覧を表示させる。ここにテーブル（table1）があることを確認。
結果省略

**④select * from table1;コマンドを打つ**
table1のすべて(\*)のカラムを表示させる。
\*の代わりにカラム名を指定するとそれが表示できる。
この時コマンドの最後に**¥G**を付加すると結果を縦に並べる。
→データの横比較はやりにくくなるけど、表示が整理されてターミナル上でデータがそれぞれ見やすくなる。


**④'-1　desc table1;でテーブルが持つカラム名を表示する**
(describe table1もしくはshow columns from userでも良い。)
そうするとそのテーブルが持つ全てのカラムが表示される。

**④'-2 select col1 from table1;でcol1というカラムの中身を表示させる**
table1もcol1も大文字・小文字の違いに注意すること。
　


#接続ユーザやカレントワーキングデータベースの表示

**接続ユーザ：select user();**
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+

**カレントワーキングデータベース：select database()**
+-------------+
| database() |
+-------------+
| db1         |
+-------------+

#SQLコマンド

##射影
先ほどの④は射影↓
select col1 from table1;

もし単一ではなく複数のカラムを表示したかったら、
select col1,col2,col3 from table1;
とすれば良い。

またサーバに余計な負荷を与えるという点で良くないが、データを加工することもできる。
<img width="479" alt="スクリーンショット 2016-04-18 15.05.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/88657/670e7070-9c59-9ae6-9781-bffdd5557225.png">


これはCONCAT関数でHostカラムの要素とUserカラムの要素をくっつけたカラムを新たに作り表示している。

##AS
ASによってカラムの別名をつけることができる。
<img width="517" alt="スクリーンショット 2016-04-18 15.04.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/88657/2ed4f102-4863-9d4d-3d55-4dd28549dd1f.png">

**asは省略できるから注意。**


##DISTINCT
重複データの非表示
select distinct hosts from db1;
のようにdistinctをselectの直後に置くと、結果に重複データが表示されなくなる。

##WHERE
条件付けできる便利なやつ
<img width="690" alt="スクリーンショット 2016-04-18 15.03.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/88657/26f820ed-4ccc-5c3a-8b36-fb89b72afcb7.png">

これはHostがlocalhostのやつだけを抜き出すWhere句
(127.0.0.1)がなくなってるのがわかる。


##BETWEEN
範囲による条件付け
select ~~~ from db1 where col1 between A and B
→Col1というカラムの中でA以上B以下の要素を検索する句となる。


##LIKE
select ~~~ from db1 where col1 like 'pattern'

'pattern'にマッチする要素を検索する句となる。
→%:0文字以上の任意の文字列
→_:1文字の任意の文字列

mysql> select distinct Host from user where Host='localhost' AND Host like '%local%ost';
みたいな感じ


##JOIN

データベースを結合する。
複数テーブルからの検索をする場合に用いるもの。RDBで大活躍するやつ。

###クロス結合
select * from table1,table2
あまり意味がない（と勝手に思ってる）結合方法。ググるとサジェストで「使いみち」とか出る。
これは考えられるすべての組み合わせのテーブルができる。
仮にレコードがtable1に7件,table2に5件あったら35件のレコードができる。ヤバい。

###等価結合
select * from table1,table2
where table1.elem1 = table2.elem1;

有能。一般的にはこれが使われる。
Where句に設定することで意味のある正しい組み合わせの行だけが選択される。
例では\*を使ったけど、tabel1,2の任意のカラムを取り出すこともできる。

###外部結合

select * from table1,table2
ON table1.elem1 = table2.elem1;

結合の時に結合する行が仮に存在しなくても検索結果として表示するもの。
そのため場合によっては結合後のデータにNULLが生まれることがある。


## ORDER BY

ORDER BY句を使うと並び替えできる。
select * from tabel1 where ~~ order by col1 [asc/desc]

デフォルトはASC(昇順)
カラムの値に基づいて昇順(小さいものが上)に並び替えをする。
→ORDER BYで複数カラムを選択したら、先に選択したほうを優先して並び替えをする。
→もし1つ目のカラムの要素で同値なら2つ目のカラムの要素を見る

## LIMIT

LIMIT句を使うと表示行数を制限できる。
select * from tabel1 where ~~ order by col1 [asc/desc]
LIMIT 1000

この場合は検索結果の1000行目までを出力する。

**注意点：**
SELECT * FROM table1 LIMIT 999990 , 10;
というsql文を発行すると、
「１００万行取得後、999990行を捨てて残り１０行を見る」
みたいな処理が行われて、これは激重すぎる。
↓
対処法としては
SELECT * FROM table1 WHERE \`id\` >999990 LIMIT 10;
のように主キーを使って条件を絞る。
そのあと、結果の０〜１０個目までを持ってくる文を発行することで、激重問題は回避できる！


##GROUP BY

指定したカラムに同一の値が含まれている場合それらをグループ化する。
→複数のカラムをGROUP BYで指定した場合それらのカラム全てに同一の値が含まれている場合のみグループとする。

(参照：http://www.shift-the-oracle.com/sql/group-by-having.html )