自然或人为排序顺序
Posted
技术标签:
【中文标题】自然或人为排序顺序【英文标题】:Natural or Human Sort order 【发布时间】:2017-09-12 16:00:24 【问题描述】:我已经为此工作了几个月。我只是无法获得natural
(真正的字母数字)结果。我很震惊,我无法得到它们,因为自 1992 年以来我一直能够在 RPG
中使用 EBCDIC
。
我正在寻找 SQL、VBS 或简单的 excel 或 access 中的任何解决方案。这是我的数据:
299-8,
3410L-87,
3410L-88,
420-A20,
420-A21,
420A-40,
4357-3,
AN3H10A,
K117GM-8,
K129-1,
K129-15,
K271B-200L,
K271B-38L,
K271D-200EL,
KD1051,
KD1062,
KD1092,
KD1108,
KD1108,
M8000-3,
MS24665-1,
SK271B-200L,
SAYA4008
我正在寻找的顺序是真正的字母数字顺序如下:
AN3H10A,
KD1051,
KD1062,
KD1092,
KD1108,
KD1108,
K117GM-8,
K129-1,
K129-15,
MS24665-1,
M8000-3,
SAYA4008,
SK271B-200L
库存是 7800 条记录,所以我在处理能力方面也遇到了一些问题。
任何帮助将不胜感激。
杰夫
【问题讨论】:
数字后字母如何比其他方式更自然? 真正的字母数字在字母数字字符串的每一列中首先对字母进行加权。它来自 bin 卡,然后是平面文件。固定字段宽度会导致排序问题,因为它们不是按每个字符的位置排序的。 【参考方案1】:在原生 Excel 中,您可以添加多个排序列以返回每个字符的 ASCII 码,但如果字符是数字,则在代码中添加一个大数字(例如 1000)。
然后对每个辅助列进行排序,包括表中的第一列,但不在排序中。
公式:
=IFERROR(CODE(MID($A1,COLUMNS($A:A),1))+AND(CODE(MID($A1,COLUMNS($A:A),1))>=48,CODE(MID($A1,COLUMNS($A:A),1))<=57)*1000,"")
排序对话框:
结果:
您可以使用 VBA 实现类似的算法,也可能使用 SQL。我不知道 VBS 或 Access。
【讨论】:
我喜欢这种方法的结果。我只是缺少一些关于如何创建 ASCII 排序的基础知识。有没有机会一步一步来创造你的结果? @Jeff 你不明白什么?你是如何尝试实现这一点的?你有没有在任何地方输入公式?结果如何? 我在B1中实现了公式。我了解您的思考过程是如何将每个字符列成一个 ASCii 顺序(我认为)。 @Jeff 只需选择 B1 并填写。然后选择 B1:Bn 并向右填写。然后查看屏幕截图以对每一列进行排序。 B1:Bn!!!我知道更深层次的东西,但从来没有想过横向。效果很好,但是在对每一列进行排序之后,列 a 仍然乱序。我不确定你是如何重新排序的。【参考方案2】:您可以尝试使用格式按顺序左填充字符串
select column
from my_table
order by Format(column, "0000000000")
【讨论】:
【参考方案3】:添加排序列:
, iif (left(fieldname, 1) between '0' and '9', 1, 0) sortField
etc
order by sortField, FieldName
【讨论】:
【参考方案4】:假设您在“A”列中有数据。如果你把这个公式放在“B”列=IFERROR(IF(LEFT(A1,1)+1>0,"ZZZZZZZ "&A1,A1),A1)
,它会自动在所有数值前面加上Z,这样当你对A-Z进行排序时,它们自然会出现在所有字母值之后。稍后您可以找到并替换那个有趣的 ZZZZZZ 字符串...
【讨论】:
【参考方案5】:有很多方法,但在这种情况下,构建两列分隔分隔符 (-) 的工作量可能最少。
然后您“填充”结果(空格或 0)右对齐,然后对两列进行排序。
所以在查询构建器中我们有这个:
SELECT Field1,
Format(
Mid(field1,1,IIf(InStr(field1,"-")=0,50,InStr(field1,"-")-1)),
">@@@@@@@@@@") AS Expr1,
Format(
Mid(field1,IIf(InStr(field1,"-")=0,99,InStr(field1,"-")+1)),
">@@@@@@@@@@") AS Expr2
FROM Data
当我们运行上面的原始查询时,我们会得到:
所以现在在查询生成器中,只需对第一个派生列进行排序,然后对第二个派生列进行排序。
例如:
运行查询,我们得到这个结果:
编辑:
看着你想要的结果,看起来上面的排序是错误的。我们必须正确并用 0 填充。
所以这第二次尝试:
SELECT Field1,
Left(Mid(field1,1,IIf(InStr(field1,"-")=0,30,InStr(field1,"-")-1))
& String(30,"0"),30) AS Expr1,
Left(Mid(field1,IIf(InStr(field1,"-")=0,99,InStr(field1,"-")+1))
& String(30,"0"),30) AS Expr2
FROM Data
结果是这样的:
鉴于您的表很小,那么上面的查询应该会执行得很好。
【讨论】:
以上是关于自然或人为排序顺序的主要内容,如果未能解决你的问题,请参考以下文章