SQLを学び直す その③
前回の続きです。
検索結果の加工方法
前回、前々回の記事の方法で抽出したデータを加工する方法です。
加工とは、例えば「降順に並べ替え」たり「重複を除外する」ことです。
DISTINCT
DISTINCTは、重複している行を取り除きます。
使い方は次の通り
データの種類を取得したい場面で役立つ。
ORDER BY
指定した列の値を基準に、並び替えをします。
使い方は次の通り
ASCは昇順、DESCは降順に並び替えられる。
OFFSET / FETCH
一部の行だけを取得します。
使い方は次の通り
なお、MySQLではサポートされていないので、以下の方法を使う
UNION
和集合を求める集合演算子。
SELECT文をUNIONで繋いで記述すると、結果が足し合わされる。
使い方は次の通り
片方のテーブルにしかないデータを結合する場合は、次のような使い方もできる
EXCEPT
差集合を求める集合演算子。
SELECT文をEXCEPTで繋いで記述すると、両テーブルに存在する行以外が出力する。
使い方は次の通り
INTERSECT
積集合を求める集合演算子。
SELECT文をINTERSECTで繋いで記述すると、両テーブルに存在する行が出力する。
使い方は次の通り
CASE演算子
使い方は次の通り
さまざまな関数
特定のタスクを実行するための機能。
例えば「COUNT」であれば、行数を取り出すことができる。
「LENGTH」であば、文字列の長さを取得することができる。
関数は、DBMSごとに動作が異なるため、公式ドキュメントを参照する必要性アリ。
主な関数は次の通り
関数 | 説明 |
---|---|
LENGTH |
文字列の長さを求める |
TRIM | 空白を削除する |
REPLACE | 置換 |
SUBSTRING | 指定文字目から指定文字分を抽出する |
CONCAT | 文字列を連結する |
TRIM | 空白を削除する |
ROUND | 四捨五入 |
TRANC | 指定桁で切り捨てる |
TRIM | 空白を削除する |
POWER | べき乗 |
CURRENT_TIMESTAMP | 現在日時(年,月,日,時,分,秒) |
CURRENT_DATE | 現在日付(年,月,日) |
CURRENT_TIME | 現在時刻(時,分,秒) |
CAST | 型のキャスト |
COALESCE | 最初に登場するNULL以外の値を返却する |
・・・次の記事に続きます
SQLを学び直す その②
前回の続きです。
WHERE句
WHERE句は、以下の特徴があります。
- 行の絞り込みをする
- SELECT、UPDATE、DELETE文で使う
- WHEREの後ろに条件式を記述する
WHEREで使う比較演算子
NULLの判定方法
- NULLであることを判定する場合
- NULLではないことを判定する場合
LIKE演算子
部分一致の検索をする演算子。
LIKE演算子で使えるパターン文字は以下の通り
命令文 | 説明 |
---|---|
% |
0文字以上の文字列 |
_ | 1文字 |
使い方は次の通り
BETWEEN演算子
データの範囲を指定する演算子。
使い方は次の通り
IN / NOT IN 演算子
指定の値に合致したデータを取り出す演算子
使い方は次の通り
ANY / ALL 演算子
指定の条件と値に合致したデータを取り出す演算子
使い方は次の通り
論理演算子
NOT、OR、ANDのこと。
優先順位としてはNOT > OR > ANDの並び。
・・・次の記事に続きます
SQLを学び直す その①
お仕事でSQLを使うことになったので、勉強します。
基本情報を取得するときに触れたことはあるのですが、意味不明だったので学び直し。
まずは基礎の「き」
学んだ内容をメモのように書き起こします。
SQL文のルール
SQL文の終了を、セミコロンで表せる
コメント
- ハイフン2つ
- /* */で囲む
4大命令
命令文 | 説明 |
---|---|
SELECT |
行の内容を取得する。 |
UPDATE | 行の内容を書き換える |
DELETE | 行を削除する |
INSERT | 行にデータを追加する |
SELECT文
基本的には、1行目にSELECT、2行目にFROMを記述する。
1行目のSELECTには、この命令文の後に使いたい列の名前を書く。
*を記述すれば、すべての列を取得することができる。
2行目のFROMには、取得するデータが格納されているテーブルを指定する。
3行目以降には、WHEREなどの修飾を続けて記述し、細かく条件を加えられる。
「AS」のキーワードをつけて、別名を定義することも可能。
UPDATE文
基本的には、1行目にUPDATE、2行目にはSET句を記述する。
1行目のUPDATEには、更新したいデータが存在するテーブル名を記述する。
2行目のSETには、更新したい列名、イコールの後に書き換えたいデータを記述する。
3行目以降には、WHEREなどの修飾を続けて記述し、細かく条件を加えられる。
DELETE文
基本的には、1行目にDELETE FROM、2行目にはWHERE句を記述する。
1行目のDELETE FROMには、更新したいデータが存在するテーブル名を記述する。
2行目以降には、WHEREなどの修飾を続けて記述し、細かく条件を加えられる。
INSERT文
基本的には、1行目にINSERT INTO、2行目にはVALUES句を記述する。
1行目のINSERT INTOには、データを追加するテーブル名を記述する。
さらに、その後ろにデータを追加する列名を指定する。
2行目以降には、VALUESを続けて記述し、追加するデータを記述する。
・・・次の記事に続きます
C言語 ポインタについて学んだことを書き起こす その①
初投稿です。
「学んだことはブログなどに書き込んでアウトプットすると良い」
らしいので試してみます。
今回は、C言語のポインタについて学んだことをメモ兼アウトプットします。
学ぶのに使った本は「C言語ポインタ完全制覇(ISBN978-4-7741-9381-6)」
という本です。
今回は第一章の内容をメモしていきます。
ポインタ型とは
例えば「int型」や「double型」が存在するが、それらから派生して作り出される型。
ポインタ型にさせるためには、型に「*」を付け加える。
そうすることで「intへのポインタ型」「doubleへのポインタ型」へと派生される。
ちなみに*は「間接演算子」と呼ぶ。
int iHoge; //int型
int* pHoge; //intへのポインタ型
で、このポインタ型には値として、メモリのアドレスを入れることができる。
例えば、iHogeのアドレスをpHogeに入れたいときには、変数に「&」を付け加える。
&は「アドレス演算子」と呼び、変数のアドレスを表示させるためのもの。
iHoge = 10;
pHoge = &iHoge; //iHogeのアドレスを、pHogeに代入
↓ このようにしたときのイメージ
このときの状況は、「pHogeは、iHogeを指している」と言うらしい。
次のように、ポインタ型に対して*をつけることで
指した先の値を表示することができる。
printf("%p",(void*)pHoge); //「0x01234」が表示される
printf("%d",*pHoge); //「10」が表示される
添字演算子
配列の要素を参照する [ ] を「添字演算子」と呼ぶ。
ちなみに、宣言のときの * や [ ] と、式の中に現れる * や [ ] は全く別もの。
と、本の筆者は述べてました。
この添字演算子も、ポインタと似たような性質を持っていますが
詳細は後で書きます。
ポインタ演算
C言語には、ポインタ演算という独特な機能がある。
次のようにしたとき、例えば「0x01234」が出力されるとする
int iHoge = 10;
int* pHoge = &iHoge; //iHogeのアドレスを、pHogeに代入
printf("%p\n",(void*)pHoge);
次に、pHogeに対して1加算すると、型のサイズ分だけアドレスが増加する。
「0x01234」の4バイト先なので、出力は「0x01238」になる。
※今回の例ではint型は4バイトとする
iHoge += 1;
printf("%p\n",(void*)pHoge);
ヌルポインタ
「ヌルポインタ」とは何も指していないことが保証されるポインタのことを言う。
ちなみに一昔前のネットミーム「ぬるぽ」もここから来てるんだとか。
・・・話を元に戻して
ヌルポインタを表す定数値として、通常はマクロNULLが使用されるとのこと。
自分の環境のNULLは次のようになってました。
この0という数字は、「ゼロ番地」的な意味合いになるみたいです。
C言語では、0という定数は、ポインタとして使う場合ではヌルポインタとして扱われる。
とのことです。
なので次のように、ポインタ型に対して0を代入することができます。
ただし0以外の値はただのint型になるので、環境によっては警告が出ます。
*hoge = 0; // コンパイラがNULLポインタとして読み替える。
*hoge = 3; // 環境によっては警告が出る
ただ「単に定数0を渡しているプログラムは移植性が低い」と筆者は述べてました。
ヌルポインタを表現したいときは0ではなくNULLを代入すべき、と解釈しました。
ヌル(NULL)とナル(\0)の違い
・ヌルポインタ
ポインタ変数が、有効なメモリ領域を指し示していない場合に使用される。
・ナル
文字列の終端を示す時に使用される。
よくある間違いとして、文字列の終端させるためにNULLを使うのは間違い。
hoge[len] = NULL; //間違い
配列
次の「例1」と「例2」では、同じことをしている。
int iHoge[5] = { 0 , 1 , 2 , 3 , 4}
int* pointer;
int i;
// 例1
for(i = 0; i < 5; i++) {
printf("%d\n", *( p + i ));
}
// 例2
for(i = 0; i < 5; i++) {
printf("%d\n", p[i] );
}
どちらも出力は以下のようになる。
0
1
2
3
4
まず、添字演算子 [ ] は、宣言と式では全く異なるもの
という前提があるらしい。
- 宣言で使う添字演算子 [ ] は、これが「配列である」ということを表す。
- 式の中で使う添字演算子 [ ] は、例1にある *( p + i ) の簡略記法。
という具合。
なので、ポインタ型変数 pointerに配列の先頭アドレスを渡すとき
p = &array[0]
と
p = array
は、どちらもやっていることは変わらない。
つまり、式の中での
p[ i ]
これは
*( p + i )
を略したもの、ということになるらしい。
シンタックスシュガー。
またC言語においては、関数の引数として配列を渡すことができない。
一見配列を渡しているように見えるプログラムでも
実際は、配列の先頭アドレスを渡しているだけになる。
(ということは、引数には配列の要素数も必ず渡さなければ危険ということか・・・)
つまりは、次のような関数を作ったとしても
int func1( int a[] )
int func2( int a[10] )
結局値として渡されるのは配列の先頭アドレスなので
int func3( int* a )
このような書き方をしているのと全く一緒。コンパイルによって書き換えられるらしい。
個人的に思ったのは、func1、func2の書き方は、引数として配列を渡してほしい時とか
特定の要素数だけの配列を渡してほしいときに、あえて書く時ぐらいかな?
その②に続きます。