sqlにて
abcテーブルの
datasカラムに
12桁の数値が入っています。
上3桁が991以外のランダム
上3桁が991
のデータがあり
sql文にて
上3桁が991のデータを取得
上3桁が991以外のデータを取得
する方法を教えてください。
where句での操作にはなると思うのですが
、、
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
「上3桁が991」の定義が曖昧
常識的に考えれば991000000000~991999999999かと思いますが
991や9911なども「上3桁が991」に当てはまります
またdatasカラムのデータ型の定義も必要です
#sample
質問者さんは要件定義をきちんとする癖をつけた方がよいですね。
中途半端な定義はバグの温床になります。
サンプルつけておきます
SQL
1create table abc(datas bigint(12) unsigned zerofill,index(datas)); 2insert into abc values(1),(2),(991),(990000000000),(991000000000),(991000000001),(991000000002); 3create table xyz(datas bigint(12),index(datas)); 4insert into xyz values(1),(2),(991),(990000000000),(991000000000),(991000000001),(991000000002); 5
zerofillしているかどうかでlikeで取れるかが異なります
zerofillしていないxyzは991などもヒットします
SQL
1select * from abc where datas like '991%'; 2select * from xyz where datas like '991%';
数値の抽出にlikeを使うとindexの利用効率が変わります
可能な限り数値の範囲指定するのが妥当です。
一応以下のような書き方もあります
SQL
1select * from abc where 991=truncate(datas / power(10,9),0)
※9というのは12桁から991=3桁を引いた数です。
ただし、検索の際にカラムを利用した計算が発生するとやや効率がさがります。
一般に数値の範囲はbetweenを利用します
数値の範囲ならabcとxyzで結果の相違はありませんのでabcのみ記載します。
SQL
1select * from abc where datas between 991000000000 and 991999999999;
ここで、わざわざ数値を手でいれるのも馬鹿らしいので、
「991」と「12桁」という値を与えて計算させてみます
SQL
1set @a=991,@b=12; 2select * from abc where datas between @a*power(10,@b-ceiling(log10(@a))) and (@a+1)*power(10,@b-ceiling(log10(@a)))-1
これを1文で書くと以下になります。
ただし、MySQLの場合おなじSQL文中で変数の参照される範囲が定義されていませんので
正しく範囲が指定できない可能性もありますが、ほぼ問題ないでしょう。
SQL
1select * from abc where datas between (@a:=991)*(@b:=power(10,12-ceiling(log10(@a)))) and (@a+1)*@b -1
投稿2016/12/21 02:00
編集2016/12/21 03:02総合スコア114769
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/12/21 02:14
2016/12/21 02:17 編集
2016/12/21 02:25 編集
2016/12/21 02:53
2016/12/21 03:50
0
上3桁が991のデータを取得
sql
1select datas from abc 2where datas >= 991000000000 3 and datas < 992000000000
上3桁が991以外のデータを取得
sql
1select datas from abc 2where datas < 991000000000 3 or datas >= 992000000000
投稿2016/12/21 01:51
総合スコア5572
0
12桁の数値が入っています。
これは例えば000000000991
みたいな先頭が0になってしまうケースは存在せず、
100000000000 ~ 999999999999
の範囲を指していますか?
そうであればtkturbo さんの仰るやり方が最善です。
一撃限りで実行速度を気にしないのであれば、
int(20)指定のカラムもlikeを使って暗黙的に型変換させれば意図通り取得できます(確認済みです)
SQL
1select datas 2from abc 3where datas like '991%'
もし取りうる範囲が0 ~ 999999999999
かつ、速度を気にするのであれば少し面倒です。
一例としてはこんな感じですかね?
SQL文をスクリプト言語で生成して投げてもいいかもしれません。
SQL
1select datas from abc 2where datas between 991000000000 and 991999999999 3 or datas between 99100000000 and 99199999999 4 or datas between 9910000000 and 9919999999 5-- 以下省略
投稿2016/12/21 02:34
総合スコア21158
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/12/21 02:52
2016/12/21 05:38 編集
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。