3

以下是字符串的一些示例(主要是地址):

12
20
43-B
43-C
123
2500

现在我把它们放在我认为“正确”的顺序中。如果我将这些值放在数据库表的列中并在 MySQL 搜索中返回这些值,我会得到:

12
123
20
2500
43-B
43-C

显然这是不正确的——20不大于123

如果我可以保证该值由纯整数组成,则很容易弄清楚这一点,但是当您输入43-Band 43-C(或什12A至或其他)时,我们就会开始遇到问题。但是,我不能简单地去掉数字!我不完全确定它在这一点上代表什么,但我确实有诸如40W1.

就个人而言,我会将其排序在 40 而不是 4000 之下,但这是一种非常罕见的极端情况,所以我不太担心这个特定的例子。不过,我确实需要记住这些字母,因为40B会在之前出现40C——但我也希望40-B在之前出现40C。很棘手,对吧?我知道。

不过,我愿意假设只有字母数字字符(即-从字符串中删除)。

我想要做的是将该字符串转换为一系列绝对可排序的数字。

例如,43-B可能会变成10000031205(填充)之类的东西,并与行的其余部分一起存储在数据库中。当我搜索我的地址时,我现在可以按排序列进行排序,一切都井井有条!

我不能做的事情:

  • 在运行时直接比较它们
  • 在 MySQL 中进行此搜索(该值需要逐行计算)
  • 在 PHP 中使用 sort/asort/ksort 或任何排序函数

我需要一个可以存储在我的数据库或搜索索引中的值,以便以后进行排序!

不幸的是,到目前为止,我的所有尝试都未能产生我想要的结果。有任何想法吗?

4

5 回答 5

2

我会使用 2 个排序列,如果您使用 PHP,则在 sql 中sortNumber int, sortText varchar存储在第一列中,在另一列中存储不带任何符号的字母(一次运行的结果(我不知道 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 回答
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 回答
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');

select a, lpad(cast(a as unsigned), 20, 0) from cmp
按 lpad(cast(a as unsigned), 20, 0) 排序;

+------+----------------------------------+
| 一个 | lpad(cast(a as unsigned), 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 回答