SQLite3構文 列制約(collate)
照合シーケンス。比較方法の指定。デフォルトはbinary
。正確には制約ではない。
成果物
情報源
照合シーケンス
組込
collater | 概要 |
---|---|
binary |
テキストエンコーディングのmemcmp で比較する |
nocase |
binary 同様だがアルファベット26字の大文字を小文字にしてから比較する |
rtrim |
binary 同様だが末尾のスペース文字を無視する |
rtrim
だと末尾のスペースが多かろうが少なかろうが、insert
した順(たぶんrowid
順?)になると思われる。binary
,nocase
は末尾スペース数の大小によりソートされる。そもそも挿入時にデータをtrim()
したほうがいいのでは?
組込でない照合シーケンスを使う方法は以下。
- https://qiita.com/Nanashia/items/21f2c4b6fbd68db13d3e
- https://www.sqlite.org/src/artifact?ci=trunk&filename=ext/icu/README.txt
- SQLite3拡張 ICUでcollateする
テーブル生成
0.sql
create table T( A int collate binary, B int collate nocase, C int collate rtrim ); select sql from sqlite_master;
エラーなく実行されたことを確認。
CREATE TABLE T( A int collate binary, B int collate nocase, C int collate rtrim )
binary
1_binary.sql
create table T(A text collate binary); insert into T values('A'); insert into T values('a'); insert into T values('B'); select A from T; select A from T order by A asc; select A from T order by A desc;
select A from T; A a B select A from T order by A asc; A B a select A from T order by A desc; a B A
nocase
1_nocase.sql
.print ===== A,a ===== create table T(A text collate nocase); insert into T values('A'); insert into T values('a'); insert into T values('B'); .echo on select A from T; select A from T order by A asc; select A from T order by A desc; .echo off drop table T; .print ===== a,A ===== create table T(A text collate nocase); insert into T values('a'); insert into T values('A'); insert into T values('B'); .echo on select A from T; select A from T order by A asc; select A from T order by A desc; .echo off
===== A,a ===== select A from T; A a B select A from T order by A asc; A a B select A from T order by A desc; B A a ===== a,A ===== select A from T; a A B select A from T order by A asc; a A B select A from T order by A desc; B a A
nocase
はA
とa
を同値とみなす。同値のときはおそらく内部値rowid
を第2キーとしてソートするのだろう。rowid
は挿入タイミングでインクリメントされる。つまり挿入タイミングによってはA
,a
にもなるし、a
,A
にもなるということ。
rtrim
.print ===== RTRIM ===== create table T(id integer primary key, A text collate rtrim); insert into T(A) values('A'); insert into T(A) values('a'); insert into T(A) values('B'); .echo on insert into T(A) values('C'); insert into T(A) values('C '); insert into T(A) values('C '); select * from T; select * from T order by A asc; select * from T order by A desc; .echo off .print ===== BINARY ===== create table U(id integer primary key, A text collate binary); insert into U(A) values('A'); insert into U(A) values('a'); insert into U(A) values('B'); insert into U(A) values('C'); insert into U(A) values('C '); insert into U(A) values('C '); .echo on select * from U; select * from U order by A asc; select * from U order by A desc; .echo off
===== RTRIM ===== insert into T(A) values('C'); insert into T(A) values('C '); insert into T(A) values('C '); select * from T; 1|A 2|a 3|B 4|C 5|C 6|C select * from T order by A asc; 1|A 3|B 4|C 5|C 6|C 2|a select * from T order by A desc; 2|a 4|C 5|C 6|C 3|B 1|A .echo off ===== BINARY ===== select * from U; 1|A 2|a 3|B 4|C 5|C 6|C select * from U order by A asc; 1|A 3|B 4|C 6|C 5|C 2|a select * from U order by A desc; 2|a 5|C 6|C 4|C 3|B 1|A .echo off
rtrim
のときは同じC
が必ず4
,5
,6
の順になっている。ところがbinary
のときはC
が昇順では4
,6
,5
で、降順では5
,6
,4
だったりする。
rtrim
は末尾スペースを無視した上、同値ならrowid
順にソートしているのだろう。対してbinary
は末尾スペースが少ない順、多い順にソートされている。
比較式
select 'A' = 'a'; select 'A' = 'a' collate binary; select 'A' = 'a' collate nocase; select 'A' = 'A '; select 'A' = 'A ' collate rtrim;
select 'A' = 'a'; 0 select 'A' = 'a' collate binary; 0 select 'A' = 'a' collate nocase; 1 select 'A' = 'A '; 0 select 'A' = 'A ' collate rtrim; 1
比較方法 | collate |
---|---|
大文字小文字を無視 | collate nocase |
末尾スペースを無視 | collate rtrim |
両方は出来ないと思う。大文字小文字を無視しつつ末尾スペースも無視する方法はないのだろう。試しに
AND
で繋いでもエラーになった。
select 'A' = 'a ' collate nocase and rtrim;
Error: near line 7: no such column: rtrim
select 'A' = 'a ' collate nocase and collate rtrim;
Error: near line 8: near "collate": syntax error
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13
- bash 4.4.12(1)-release
- SQLite 3.29.0
- MeCab 0.996ユーザ辞書
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux
前回まで
- SQLite3学習 俯瞰まとめ
- SQLite3学習 環境構築まとめ
- SQLite3学習 インタフェースまとめ(C言語、CLI、対話モード、Tcl...)
- SQLite3学習 ドットコマンドまとめ
- SQLite3学習 JSON拡張まとめ
- SQLite3学習 FTSまとめ(ICU, MeCab)
- SQLite3学習 再帰クエリ(WITH RECURSIVE)
- SQLite3学習 R-Treeモジュール
- SQLite3学習 Geopoly(2次元ベクタ画像の生成)
- SQLite3学習 拡張関数(generate_series)
- SQLite3学習 拡張ライブラリ数学関数(extension-functions.c)
- SQLite3学習 謎と名前
- SQL文の分類(DDL,DML,TCL,DCL)
- SQL構文 alter(rename)
- SQL構文 alter(add column)概要
- SQL構文 alter(add column)制約
- SQL構文 alter(add column)sqlite_master変更しても反映されない
- SQL構文 alter(add column)スキーマ再定義(テーブル再作成による定義変更)
- SQL構文 analyze
- SQL構文 attach/detach
- SQLite3構文 begin,end,commit,rollback,savepoint(deferred,immediate,exclusive)
- SQLite3構文 コメント
- SQLite3構文 create/drop
- SQLite3構文 index(create/drop)
- SQLite3構文 table(create/drop)
- SQLite3構文 列制約(default)