MySQL String Position和Substring排序

时间:2016-02-02 16:48:06

标签: mysql

要排序的示例数据:

  

xy3abc
  y3bbc
  z3bd

排序顺序必须是abc,bbc,bd,无论数字前面是什么。

我试过了:

SELECT 
  *, 
  LEAST(
    if (Locate('0',fcccall) >0,Locate('0',fcccall),99),
    if (Locate('1',fcccall) >0,Locate('1',fcccall),99),
    if (Locate('2',fcccall) >0,Locate('2',fcccall),99),
    if (Locate('3',fcccall) >0,Locate('3',fcccall),99),
    if (Locate('4',fcccall) >0,Locate('4',fcccall),99),
    if (Locate('5',fcccall) >0,Locate('5',fcccall),99),
    if (Locate('6',fcccall) >0,Locate('6',fcccall),99),
    if (Locate('7',fcccall) >0,Locate('7',fcccall),99),
    if (Locate('8',fcccall) >0,Locate('8',fcccall),99),
    if (Locate('9',fcccall) >0,Locate('9',fcccall),99)
  ) as locationPos,
  SUBSTRING(fcccall,locationPos,3) as fccsuffix
FROM memberlist
ORDER BY locationPos, fccsuffix

但是locationPos在子串函数调用

上给出了错误

2 个答案:

答案 0 :(得分:1)

无法通过别名locationPos在同一SELECT列表中的另一个表达式中引用该表达式。

复制整个表达式将是SQL的方法。 (是的,重复整个表达是丑陋的。)

另一种(性能较低)方法是使用您的查询(减去fccsuffix表达式)作为内联视图。外部查询可以将指定的locationPos别名引用为列名。

举个简单的例子:

SELECT v.locationPos
  FROM ( SELECT 'my really big expression' AS locationPos
           FROM ...
       ) v

这种使用内联视图("派生表")的方法可能会对大集合产生一些严重的性能影响。

但是对于原始表现,重复表达是可行的方法:

SELECT *
     , LEAST(
        if (Locate('0',fcccall) >0,Locate('0',fcccall),99),
        if (Locate('1',fcccall) >0,Locate('1',fcccall),99),
        if (Locate('2',fcccall) >0,Locate('2',fcccall),99),
        if (Locate('3',fcccall) >0,Locate('3',fcccall),99),
        if (Locate('4',fcccall) >0,Locate('4',fcccall),99),
        if (Locate('5',fcccall) >0,Locate('5',fcccall),99),
        if (Locate('6',fcccall) >0,Locate('6',fcccall),99),
        if (Locate('7',fcccall) >0,Locate('7',fcccall),99),
        if (Locate('8',fcccall) >0,Locate('8',fcccall),99),
        if (Locate('9',fcccall) >0,Locate('9',fcccall),99)
       ) AS locationPos
     , SUBSTRING(fcccall
       , LEAST(
          if (Locate('0',fcccall) >0,Locate('0',fcccall),99),
          if (Locate('1',fcccall) >0,Locate('1',fcccall),99),
          if (Locate('2',fcccall) >0,Locate('2',fcccall),99),
          if (Locate('3',fcccall) >0,Locate('3',fcccall),99),
          if (Locate('4',fcccall) >0,Locate('4',fcccall),99),
          if (Locate('5',fcccall) >0,Locate('5',fcccall),99),
          if (Locate('6',fcccall) >0,Locate('6',fcccall),99),
          if (Locate('7',fcccall) >0,Locate('7',fcccall),99),
          if (Locate('8',fcccall) >0,Locate('8',fcccall),99),
          if (Locate('9',fcccall) >0,Locate('9',fcccall),99)
         ),3
       ) AS fccsuffix
  FROM memberlist
 ORDER BY locationPos, fccsuffix

不幸的是,使用MySQL时,无法在相同的 SELECT列表中的表达式中引用locationPos列的结果。

答案 1 :(得分:0)

我只喜欢一个数字:

  SELECT *
    FROM memberlist
ORDER BY SUBSTRING(fcccall, 
           LOCATE('0',fcccall)+
           LOCATE('1',fcccall)+
           LOCATE('2',fcccall)+
           LOCATE('3',fcccall)+
           LOCATE('4',fcccall)+
           LOCATE('5',fcccall)+
           LOCATE('6',fcccall)+
           LOCATE('7',fcccall)+
           LOCATE('8',fcccall)+
           LOCATE('9',fcccall),3)

但明智的方法不是在一个字段中存储两个独立的信息位。