【问题标题】: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 卡,然后是平面文件。固定字段宽度会导致排序问题,因为它们不是按每个字符的位置排序的。

标签: sql excel ms-access


【解决方案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&gt;0,"ZZZZZZZ "&amp;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
        

        结果是这样的:

        鉴于您的表很小,那么上面的查询应该会执行得很好。

        【讨论】:

          猜你喜欢
          • 2013-01-07
          • 1970-01-01
          • 2023-03-20
          • 1970-01-01
          • 2016-08-19
          • 1970-01-01
          • 2010-11-22
          • 1970-01-01
          • 2014-05-21
          相关资源
          最近更新 更多