teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

修正

2016/12/21 03:02

投稿

yambejp
yambejp

スコア117837

answer CHANGED
@@ -27,7 +27,15 @@
27
27
  ```
28
28
  数値の抽出にlikeを使うとindexの利用効率が変わります
29
29
  可能な限り数値の範囲指定するのが妥当です。
30
+
31
+ 一応以下のような書き方もあります
32
+ ```SQL
33
+ select * from abc where 991=truncate(datas / power(10,9),0)
34
+ ```
35
+ ※9というのは12桁から991=3桁を引いた数です。
36
+ ただし、検索の際にカラムを利用した計算が発生するとやや効率がさがります。
37
+
30
- なお一般に数値の範囲はbetweenを利用します
38
+ 一般に数値の範囲はbetweenを利用します
31
39
  数値の範囲ならabcとxyzで結果の相違はありませんのでabcのみ記載します。
32
40
 
33
41
  ```SQL

1

sample

2016/12/21 03:02

投稿

yambejp
yambejp

スコア117837

answer CHANGED
@@ -3,4 +3,49 @@
3
3
  常識的に考えれば991000000000~991999999999かと思いますが
4
4
  991や9911なども「上3桁が991」に当てはまります
5
5
 
6
- またdatasカラムのデータ型の定義も必要です
6
+ またdatasカラムのデータ型の定義も必要です
7
+
8
+ #sample
9
+ 質問者さんは要件定義をきちんとする癖をつけた方がよいですね。
10
+ 中途半端な定義はバグの温床になります。
11
+
12
+ サンプルつけておきます
13
+ ```SQL
14
+ create table abc(datas bigint(12) unsigned zerofill,index(datas));
15
+ insert into abc values(1),(2),(991),(990000000000),(991000000000),(991000000001),(991000000002);
16
+ create table xyz(datas bigint(12),index(datas));
17
+ insert into xyz values(1),(2),(991),(990000000000),(991000000000),(991000000001),(991000000002);
18
+
19
+ ```
20
+
21
+ zerofillしているかどうかでlikeで取れるかが異なります
22
+ zerofillしていないxyzは991などもヒットします
23
+
24
+ ```SQL
25
+ select * from abc where datas like '991%';
26
+ select * from xyz where datas like '991%';
27
+ ```
28
+ 数値の抽出にlikeを使うとindexの利用効率が変わります
29
+ 可能な限り数値の範囲指定するのが妥当です。
30
+ なお一般に数値の範囲はbetweenを利用します
31
+ 数値の範囲ならabcとxyzで結果の相違はありませんのでabcのみ記載します。
32
+
33
+ ```SQL
34
+ select * from abc where datas between 991000000000 and 991999999999;
35
+ ```
36
+
37
+ ここで、わざわざ数値を手でいれるのも馬鹿らしいので、
38
+ 「991」と「12桁」という値を与えて計算させてみます
39
+
40
+ ```SQL
41
+ set @a=991,@b=12;
42
+ select * from abc where datas between @a*power(10,@b-ceiling(log10(@a))) and (@a+1)*power(10,@b-ceiling(log10(@a)))-1
43
+ ```
44
+
45
+ これを1文で書くと以下になります。
46
+ ただし、MySQLの場合おなじSQL文中で変数の参照される範囲が定義されていませんので
47
+ 正しく範囲が指定できない可能性もありますが、ほぼ問題ないでしょう。
48
+
49
+ ```SQL
50
+ select * from abc where datas between (@a:=991)*(@b:=power(10,12-ceiling(log10(@a)))) and (@a+1)*@b -1
51
+ ```