SQLは、検索範囲などの条件を指定し、それに該当するデータを抽出する処理でよく使われます。なお、この条件を作る場合、範囲を数字で指定するだけではありません。日付や時間などもよく使われます。そこで今回は、日付や時間を含む、範囲を指定したSQLの作り方を解説します。
SQLを使うメリットは抽出
今使われている情報システムでは、必ずと言っていいくらい、データベース管理ソフトが利用されています。そして、データベース管理ソフトを使う理由は、大量のデータの中から、必要なデータのみを効率よく抽出する機能があるからです。
そこで、SQLを作るうえで重要になるのが、抽出するデータの条件、特に抽出範囲をどうやって指定するかです。次から、SQLの条件の作り方について簡単に解説します。
条件に一致するもののみ抽出
条件としてIDを指定するなど、SQLでは、特定の1つのデータだけを抽出する条件が、よく使われます。また、ある条件に一致するデータを抽出することで、扱うデータの範囲を狭めるため使われるケースもあります。
なお、データベース管理ソフトは、非常に効率よくデータを比較する機能を持っていますが、巨大なデータを扱えばそれなりに処理に時間がかかります。さらに、検索条件が複雑になれば、その分サーバーに負荷がかかり、システムが時間内に応答といったトラブルや、サーバーが止まる原因にもなりかねません。
そのため、事前に、共通する条件でデータを絞り込み、その中から指定された範囲に該当するデータを抽出する、といった抽出プランを立てるのが重要です。
2つの値の範囲内のデータを抽出
SQLによるデータの抽出でよく使われるのが、2つの値の範囲内にあるかをチェックし、該当するデータのみ抜き出すという条件です。なお、範囲の指定には、金額や数量などの数値の他に、日付や日時が使われることもあります。
なお、この場合に注意が必要なのが、範囲を指定する数や日付、時刻に一致した場合を含めるか、含めないかです。例えば、between演算子は、一回の処理で指定した範囲のデータを抽出できますが、指定した数を含んで抽出します。そのため、指定した数を含まないケースでは、「」の2つの演算子でデータを抽出し、そのANDをとるといったSQLで処理します。
サブクエリーを活用する
複数の条件に一致したデータの中から、ある値の範囲内に該当するデータを抽出する、といった複雑なケースは珍しくありません。このような場合は、サブクエリーを活用し、複数の条件に一致するデータだけを集めたテーブルを一時的に作成した上で、そのテーブルから範囲内のデータを抽出するSQLを作成します。
なお、サブクエリーで作成した一時的なテーブルに対してinner join句を使うと、範囲を限定したテーブルを合成することが可能です。このように、SQLでは、この機能を上手く活用することで、複雑な条件のデータを効率良く抽出するテクニックもあります。
範囲を指定するならbetween演算子が有利
2つの数字の範囲にあるデータを抽出する場合、SQLのbetween演算子が利用できます。次から、このbetween演算子について簡単に解説します。
between演算子とは
between演算子とは、where句で検索条件を設定する際に使える、ある値以上、かつ、ある値以下の条件に一致する要素を抽出するための演算子で、次のように書きます。
where 列名 between 下限値 and 上限値
なお、between演算子では、下限値と上限値を含む条件で検索するので、以下「=」演算子のANDと同じ結果になります。
between演算子を使ったSQLの例 select * from sample_table where 数値 between 1000 and 9999;
上記のSQLは、下記のSQLと同じです。
上の例を以上と以下の演算子で書き換えたSQL select * from sample_table where 数値 >= 1000 and 数値 <= 9999;
between演算子の方が処理は速い
範囲を指定して、それに該当するデータを抽出するなら、2つの演算子で条件を指定し、そのANDを取るよりも、between演算子を使った方が処理は早くなるので、ぜひ、活用してください。
これは、where句では、ANDやORがあると、指定された条件に一致するかどうかを毎回全レコード文チェックし、その結果からANDやORを適用したリストを作ります。しかし、between演算子は、1回のチェックで2つの数字の範囲にあるかどうかをチェックすることが可能です。そのため、以上と以下の比較演算子でANDを取る書き方よりも、早く処理できます。
指定された期間のデータを抽出するには
Webシステムでは、登録日などの日付をデータベースに格納しておき、ある期間を範囲として指定し、その日付のデータを検索するケースがよくあります。次から、SQLにおける日付の範囲の検索方法について解説します。
日付を数字に変換すれば範囲での抽出が可能
データベースに格納された日付を検索し、指定された期間内のデータだけ抽出する場合、日付を数字に変換して扱うことで、範囲に含まれるかどうかをチェックします。
なお、SQLでは、日付を扱うためのデータタイプとしてDATE型やDATESTAMP型が利用できます。このDATE型やDATESTAMP型で登録された日付とは、実は数字です。そのため、そのままでも比較できます。さらに、関数を利用して、何月、または、何日かを数字として抜き出して比較することも可能です。
日付の範囲を検索する例
例えばMySQLでは、日付として認識するフォーマットがあり、それに従って書かれている文字列は、日付として認識されます。そのため、日付の範囲の指定する際、そのフォーマットに従っていれば、日付を書くだけで範囲の指定が可能です。
日付の範囲を指定したSQLの例 select * from sample_table \ where \ 日付 >= '2020-4-1' and 日付 <= '2020-5-31';
上の例は、DATE型で定義された「日付」に格納された日付の範囲を検索するSQLで、’2020-4-1’から’2020-5-31’に該当するデータを抽出します。
なお、日付として認識する書き方として、次の書き方が可能です。
‘YYYY-MM-DD’ 例’2019-09-07′
‘YY-MM-DD’ 例’19-09-07′
‘YYYYMMDD’ 例’20190907′
‘YYMMDD’ 例’190907′
さらに、区切り文字として、「-」の代わりに、「.」「/」「@」が使えます。
‘YYYY-MM-DD’ ‘2019-09-07’
‘YYYY.MM.DD’ ‘2019.09.07’
‘YYYY/MM/DD’ ‘2019/09/07’
‘YYYY@MM@DD’ ‘2019@09@07’
指定された時刻のデータを抽出するには
先ほど、指定された期間のデータを抽出する方法を解説しましたが、指定された時刻のデータを抽出することもできます。
SQLで時刻を扱うデータ型はTIME型ですが、よく使われるのは日付を含むDATETIME型またはTIMESTAMP型です。これらは、レコードを記録した日時を保存するのによく使われます。そして、時刻を比較する場合は、そのような日時のデータから時刻だけを取り出して比較するのが一般的です。
時刻の範囲を検索する例
次に、DATETIME型で登録した日時から時刻のみを比較し、条件となる時刻の範囲内にあるレコードを抽出する例を紹介します。
DATETIME型で登録された時刻の範囲を検索する例 select * from logtable \ where ( extract(hour from timestamp) >= 10 ) and \ ( extract(hour from timestamp) < 12 );
この例は、extract関数を使い、DATETIME型のtimestampから時間のみ数字で取り出し、それが10以上12未満、つまり、10時から12までのデータを抽出するSQLです。
まとめ
Webシステムからデータベース管理ソフトを使う場合、よく使われるのは、指定した範囲のデータを抽出するSQLです。そして、数字や特定の文字が含まれるデータの抽出の他に、日付や時刻の範囲を指定するケースもよく見かけます。
もし、2つの数字の範囲のデータを抽出するなら、今回解説したように処理速度で有利なbetween演算子を使いましょう。また、SQLでは日付や時刻の扱いは特別です。DATE型やDATATIME型でテーブルを作成し、SQL特有の日付の書き方や時刻に変換して利用してください。