3

文字列 (主にアドレス) の例を次に示します。

12
20
43-B
43-C
123
2500

今、私はそれらを「正しい」順序と考えるものに入れました。DB テーブルの列にこれらの値があり、MySQL 検索でそれらを返すと、次のようになります。

12
123
20
2500
43-B
43-C

明らかにそれは正しくありません -20は より大きくありません123

値が純粋な整数で構成されていることを保証できれば、これを理解するのは非常に簡単ですが、43-Band 43-C(12Aまたは何でも) を投入すると、問題が発生し始めます。ただし、単純に数字を取り除くことはできません。この時点でそれが何を表しているのか完全にはわかりませんが、 などの値があります40W1

個人的には、4000 ではなく 40 未満に分類しますが、これは非常にまれなエッジ ケースなので、その特定の例についてはあまり心配していません。ただし、文字を覚えておく必要があります。なぜなら、前40B来る40Cから40-Bです40C。トリッキーですよね?知っている。

ただし、英数字のみを想定しています (つまり-、文字列から を取り除きます)。

私がやりたいことは、その文字列を確実にソート可能な一連の数値に変換することです。

たとえば、 (パディングされた)43-Bのようなもの10000031205になり、残りの行と共にデータベースに格納される可能性があります。住所を検索すると、並べ替え列で並べ替えることができるようになり、すべてが順番に表示されます!

私ができないこと:

  • 実行時に直接比較する
  • MySQL でこの検索を実行します (値は行ごとに計算する必要があります)。
  • PHP で sort/asort/ksort または任意のソート関数を使用する

データベースまたは検索インデックスに格納できる値が必要で、後で並べ替えることができます。

残念ながら、これまでの試みはすべて、探している結果を生み出すことができませんでした。何か案は?

4

5 に答える 5

2

それが最も効率的な形式であるとは言いませんが、うまくいくでしょう。負の数はないと仮定します。

5 桁にパディングしましたが、パディングは数値シーケンスの最大桁数よりも大きくする必要があります。

$input = '43-B1';
$nat = preg_replace_callback('#\d+#', function($m) {
    return str_pad($m[0], 5, '0', STR_PAD_LEFT);
}, $input);
echo $nat;

デモ http://codepad.viper-7.com/kefb4L

于 2012-06-26T18:14:14.327 に答える
2

私は2つの並べ替え列を使用し、PHPを使用する場合は最初の列に、SQLでは、他の列には記号のないsortNumber int, sortText varchar文字を保存します( 1回の実行の結果(SQLの方法はわかりません..)、および.フロートを考慮する必要がある場合は、もう少し複雑になりますが、それほど多くはありません。intval($string);CAST(column as UNSIGNED)preg_replace(array('/^-?[0-9]+/','/[^A-Z0-9]/i'),'',$input)SORT BY sortNumber, sortText

于 2012-06-26T18:09:35.203 に答える
1

次のようなものはどうですか:

preg_match('(\d*)[^a-zA-Z0-9]*(.*)', $houseNumber, $matches);
$sortable = sprintf("%08d%s", $matches[1], $matches[2]);
于 2012-06-26T18:11:53.110 に答える
1
テーブル cmp を作成します ( a varchar(255));

cmp 値に挿入 ('12')、('123')、('20')、('2500')、('43-B')、('43-C')、
('4000'), ('40w1');

cmp から a, lpad(cast(a as unsigned), 20, 0) を選択
order by lpad(cast(a as unsigned), 20, 0);

+------+----------------------------------+
| | | | lpad(キャスト(符号なし), 20, 0) |
+------+----------------------------------+
| | 12 | 00000000000000000012 |
| | 20 | 00000000000000000020 |
| | 40w1 | 00000000000000000040 |
| | 43-B | 00000000000000000043 |
| | 43-C | 00000000000000000043 |
| | 123 | 00000000000000000123 |
| | 2500 | 00000000000000002500 |
| | 4000 | 00000000000000004000 |
+------+----------------------------------+
セットで 8 行、6 つの警告 (0.00 秒)

このような例を使用して、数値以外を削除し、
自然に並べ替えることができます。

警告は実際にはショー ストッパーではありません
。文字列列から数値的に並べ替えようとしていると考えてください。

于 2012-06-26T18:20:15.803 に答える
0

数値を別の列に保存することを検討しましたか? これらがアドレスである場合、それは合理的かもしれません。また、パフォーマンスは、文字列のハッシュや処理よりも優れています。

于 2012-06-26T18:09:13.423 に答える