質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

4回答

24320閲覧

sql 検索条件を上3桁一致で検索するには?

amaguri

総合スコア227

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

1クリップ

投稿2016/12/21 01:38

sqlにて
abcテーブルの
datasカラムに
12桁の数値が入っています。
上3桁が991以外のランダム
上3桁が991
のデータがあり

sql文にて
上3桁が991のデータを取得
上3桁が991以外のデータを取得
する方法を教えてください。
where句での操作にはなると思うのですが
、、

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A.Ichi

2016/12/21 02:38

「12桁の数値が入っています。」と言われているので12桁以外は無いと思われます。datasの属性が不明です、bigintでしょうか。
guest

回答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
yambejp

総合スコア114769

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amaguri

2016/12/21 02:14

すみません日本語が悪かったのでしょうか? 上3桁というのは 一番上から3桁という意味だと思っていましたが、、違うのですか、、
yambejp

2016/12/21 02:17 編集

では991や9911もヒットさせるということでよいのですね? もしくはdatasの範囲が100000000000~999999999999であるなどの 提示が必要です
amaguri

2016/12/21 02:25 編集

991は 一番上からの上3桁になります。 なので 991〇〇〇〇 にあてはまれば検索ヒットになります。 また桁は12桁と決まっています
yambejp

2016/12/21 02:53

範囲指定のsampleつけておきました
amaguri

2016/12/21 03:50

なるほどありがとうございます!!わかりやすかったです!
guest

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

tkturbo

総合スコア5572

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amaguri

2016/12/21 03:04

すみません動かないのですが何が原因でしょうか? シングルコーテーション必要でしょうか?
tkturbo

2016/12/21 03:27

「数値」ならシングルクォーテーション不要です。 「数字」ならシングルクォーテーションが必要です。 自己解決された回答を見るに対象のデータは「数字」だったのではないですか?
amaguri

2016/12/21 03:51

なるほど! 数字と数値とで違うのですね! ありがとうございます!
guest

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

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amaguri

2016/12/21 02:52

12桁以外はありえないので between 99100略 and 991999略 ということでいいのでしょうか? ただこの場合 それ以外の場合通したらいいのでしょうか?
miyabi-sun

2016/12/21 05:38 編集

> ということでいいのでしょうか? その通りです! > それ以外の場合 全部を丸括弧で括って頭に NOT を付けます。 下記のようになります。 NOT (datas between 99100略 and 991999略 or ...)
guest

0

自己解決

where カラム名 LIKE '991%'
where カラム名 NOT LIKE '991%'
にて解決しました。

投稿2016/12/21 02:29

amaguri

総合スコア227

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2016/12/21 02:53

私の回答にsampleつけときましたが datasが必ず100000000000以上という条件がなければ 991などがヒットしますのでLIKEを利用する場合は気をつけてください
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問