SQL_重複排除と集計

今回は重複排除(distinct句)と集計(group by)の紹介です。
どちらも挙動が似ているのでまとめて紹介します。

【機能説明】

・重複排除

select文の結果について、重複を排除することができる。

・集計

指定したカラムで集計を行うことができる。
(結果として重複排除もされる)
select文で集計関数を使用することができるようになる。
(該当行数を返すCOUNT関数、最大値を返すMAX関数、最小値を返すMIN関数等)
なお、having句でgroup byで集計した結果に対して条件で抽出することができる。
(where句も同じように抽出を行うが、where句は集計前に、having句は集計後に抽出する違いがある)

【文法】

・重複排除

・集計

【対象テーブル例】

・ご意見

【使用例】

asは省略可能である。

・重複排除(distinct句)

※店舗ID=1、商品ID=4の行は2行存在するが、重複排除され1行のみ出力された。

・重複排除(group by句)

※この例のように、order by句でdistinct句と同じように重複排除を実現できる。
 しかし、本来、order by句は後述の集計で使うので、重複排除のために使うのであればdistinct句の方が意図は伝わりやすい。
 また、distinct句とorder by句で実行時間に差が出る場合もある。

・集計(count関数)

※count関数の引数にカラム名を指定すると、そのカラムがNULLではない件数を返す。
 例えば、count(ご意見件数)なら、店舗ID=1、商品ID=4の行のご意見件数は1になる。

・集計(having句での抽出)


いかがでしたでしょうか。

今回は、SQLでの重複排除と集計について記事を書きました。
SQLではこのような操作も簡単に書くことができます。
特に、運用作業でデータ加工する時に重宝すると思います。

次回は、SQLを入れ子で実行する副問合せ・相関副問合せについて取り上げたいと思います!

SQL_取得結果に対する条件判定

SELECT文で取得した結果に対して、CASE式を使用することで条件判定が可能です。
条件判定を行うことで、SQL文の出力結果を変えることができます。
プログラムのIF文の判定をSQL文の中で行っているようなイメージであり、プログラムを作るまでもない運用作業で使用する他、プログラムに組み込む場合も使い方次第でプログラムの可読性・保守性を高めることができる場合があります。

なお、NULLの時に出力結果を変えるだけであればCOALESCE関数の方がスマートなので、これも併せて紹介します。

【文法】

・CASE式(単純CASE式)

SELECT~FROMの間のカラム指定の箇所で使用する。
カラムの値に応じて返す値を指定する。

・CASE式(検索CASE式)

SELECT~FROMの間のカラム指定の箇所で使用する。
式に応じて返す値を指定する。

・COALESCE関数

SELECT~FROMの間のカラム指定の箇所で使用する。
可変長の引数を持ち、NULLではない最初の値を返す。

【対象テーブル例】

・商品

【取得例】

※ASは省略可能


いかがでしたでしょうか。

今回紹介した文法も、日々の保守運用作業の役に立つものです。
WHERE句以外の箇所でも条件を指定できることを知ると、SQLでの表現の幅が広がり、作業が効率的になります。

SELECT文の結果については、結果として表示される値を変えるだけでなく、その値の重複を排除したり、集計したりすることもできます。
こちらについては次回の記事で紹介したいと思います!

SQL_取得結果に対する演算子の利用

SELECT文で取得した結果に対して、演算子を使うことで文字列結合や計算が可能です。
これを使うことで、DBから抜き出してきたデータを他人に見せる時の加工が用意になります。
また、プログラムで実装していたロジックをSQL文に組み込むことが可能になりますし、副問い合わせで使用すれば「抽出→抽出結果をプログラムで加工→加工した結果を用いて再度抽出」としていたものを1つのSQL文にまとめることもできます。

【文法】

・文字列結合

演算子「||」を用いることで前後の文字列の結合が可能。
例えば、「商品名||’_特価品’」とすれば、商品名の取得結果の後ろに「_特価品」という文字列を追加し出力することができる。

・計算

算術演算子(+,-,*,/,%)を用いることで取得結果の計算が可能。
例えば、「売値 * 0.8」とすれば、売値の取得結果について0.8をかけた値を出力することができる。

【対象テーブル例】

・商品

【取得例】

※ASは省略可能


いかがでしたでしょうか。

SQLのSELECT文で取得した結果を加工できるのは意外だったかもしれませんが、特に日々の保守運用作業が容易になるメリットが大きいので、覚えておいて損は無い文法です。

なお、取得した結果を加工する代表的な方法としては、CASE文もあります。
こちらについては次回の記事で紹介したいと思います!

SQL_テーブル結合の基礎的な文法

今回はSQL文のテーブル結合について、例を出して簡単にまとめます。

プログラムを作る時に必要になるだけでなく、テストデータを確認する時に使用することもありますし、障害対応で時間が限られている時にアドリブで入力することもあります。
慣れておいて損はない文法なので、開発作業で使う機会があれば積極的に使うことを勧めます。

以下では、結合の種類について簡単に書いた後、結合例を記載します。

【結合の種類】

結合には下記の五種類があります。

・内部結合

JOIN句の左側のテーブルと右側のテーブルについて、結合条件に合致するレコードのみ出力する。

・左外部結合

JOIN句の左側のテーブルについては、結合条件に合致するレコードのみでなく、結合条件に合致しないレコードも出力する。
結合条件に合致しないレコードについては、右側のテーブルの項目は全項目NULLとする。

・右外部結合

JOIN句の左側のテーブルについては、結合条件に合致するレコードのみでなく、結合条件に合致しないレコードも出力する。
結合条件に合致しないレコードについては、左側のテーブルの項目は全項目NULLとする。

・完全外部結合

JOIN句の左側のテーブルと右側のテーブルについて、結合条件に合致するレコードのみでなく、結合条件に合致しないレコードも出力する。
結合条件に合致しないレコードについては、片方のテーブルの項目は全項目NULLとする。

・直積結合

JOIN句の左側のテーブルと右側のテーブルについて、全てのレコードの組み合わせを出力する。

【対象テーブル例】

・子会社A取扱商品

・子会社B取扱商品

※両テーブル共に商品IDは主キー

【結合例】

※「AS」「INNER」「OUTER」は省略可能
※「AS」でテーブル別名を使用しない場合は、正式なテーブル名をカラム名の前につけて参照する
※ON句の代わりにWHERE句で結合条件を指定することも可能

・内部結合

・左外部結合

・右外部結合

・完全外部結合

・直積結合


以下、実務上の補足です。

・頻出の結合

五種類の結合の中では、内部結合と左外部結合が頻出です。

・外部結合による存在チェック

外部結合は存在チェックに使うこともあります。
結合条件に主キーを指定した場合、結合条件に合致しないケース以外で主キー項目がNULLになることはないので、主キー項目がNULLなら存在しない、NULLでなければ存在する、と判定することができます。
存在チェックは副問い合わせ(IN句)やEXISTS句でも可能ですが、外部結合を使うと他テーブルの情報を取得しつつ存在チェックも同時に行えるので、取得結果を一つにまとめたい時やループで1レコードずつ回していく時等に効果を発揮します。
もちろん、これだけを覚えれば良いというわけでなく、プログラムの可読性を考えると本当に存在チェックだけをしたい時は副問い合わせ(IN句)やEXISTS句を使うべきですし、性能要件がシビアな時もどれを採用するのがベストか調査・検討する必要があります。

・バグによる直積結合

直積結合は、意図して使うことよりも、バグによりそうなってしまうことの方が多いです。
具体的には「テーブル結合の失敗パターン」に書いていますが、結合キーの指定が不足することで直積結合になってしまいます。
直積結合がどのような結合なのかを知っておくことで、この類のバグをすぐに見つけることができるので、意図的に使わないにしても知っておいて損はありません。


いかがでしたでしょうか。

今回の記事では、SQLの基礎的な文法であり、初学者が躓きやすい文法であるテーブル結合について取り扱いました。
基本情報処理技術者試験のような試験の対策を意識しつつ、情報を補足し実務でも役立てやすくなるように意識しました。

SQLの文法については、これからも記事を書いていこうと思います!

2進数や16進数を説明する時に使っている図

私が2進数や16進数を説明する時に使っている図はこれです。
基数計算を本質的に理解できる図になっていると思います。


私たちが日常で使っているのは10進数です。
10に達すると次の桁に繰り上がるという概念です。

対して、2進数は2に達すると次の桁に繰り上がるという概念であり、ビットのON/OFFの2値で制御するコンピューターにとっては2進数の方が都合が良いです。
16進数は16に達すると次の桁に繰り上がるという概念であり、2の倍数となっている(16進数2桁で256通り=8ビット=1バイトの情報を扱える)ため、これもコンピューターにとっては都合が良いものになっています。

「○進数は○に達すると次の桁に繰り上がるという概念である」ということさえ覚えておけば、特に困ることはないと思います。 少なくとも私は、仕事でも趣味でも資格試験でも困ったことはないです。


基数計算は以下のように行います。

例えば、125を10進数で表す時は

  • 10*10*10の桁…1000より小さいのでここには何も入らない。
  • 10*10 の桁…ここを1にすれば、125の内100は表現できる。残り25。
  • 10 の桁…ここを2にすれば、25の内20は表現できる。残り5。
  • 1 の桁…ここを5にすれば、残りの5を全て表現できる。

→125
と表すことができます。

2進数もこれと同じです。
例えば、7を2進数で表す時は

  • 2*2*2の桁…8より小さいのでここには何も入らない。
  • 2*2 の桁…ここを1にすれば、7の内4は表現できる。残り3。
  • 2 の桁…ここを1にすれば、3の内2は表現できる。残り1。
  • 1 の桁…ここを1にすれば、残りの1を全て表現できる。

→111(2)
と表すことができます。


いかがでしたでしょうか。

参考書では、以上のような説明がされることは意外と少ないと思います。
何かを説明する時に、色々な角度で説明すると理解が深まる場合があるので、今回は独自の角度での説明を書いてみました。

参考になれば幸いです。