按字符串

时间:2016-07-27 14:55:36

标签: mysql sql string numbers

这个有点像噩梦。我正在处理现有数据库的前端,我不得不跳过箍以确保数据以正确的顺序显示。如果我可以通过Id订购,它会让我的生活变得更加简单,但是ID与数据几乎没有相关性。

这就是我的意思

ID   DATA
357  "7-1-5: Sensitive Information I can't share"
2521 "30-2-8-17: Yet more sensitive Information"
6002 "9-30: There's a 10 behind the colon, because I hate you"
8999 "2-2-4: This was populated in no particular order"
9001 "30-3: More Info."

我试图像这样订购

ID   DATA 
0001 "2-2-4: This was populated in no particular order"
0002 "7-1-5: Sensitive Information I can't share"
0003 "9-30: There's a 10 behind the colon, because I hate you"
0004 "30-2-8-17: Yet more sensitive Information"
0005 "30-3: More Info."

基本上,我需要按每次1到2位的数字排序,这些数字一次又一次地用短划线分隔,以便1-3在1到1之后出现,在1-1之后出现50。

就像我在开始时所说的那样,我是一个前端人员,所以在MySql中执行的工作比单独做的更多。任何帮助都会非常感激。

编辑:我刚刚在另一张表中指出了这个外键,这使得情况变得更糟。

2 个答案:

答案 0 :(得分:1)

尝试此查询:

SELECT col
FROM yourTable
ORDER BY SUBSTRING(col, INSTR(col, '"') + 1, INSTR(col, ':') - INSTR(col, '"') - 1)

SUBSTRING(...)子句中的ORDER BY术语仅从文本中提取ID。据推测,您希望它们从左到右按数字排序。即使它们是varchar,数值排序仍然可以工作。

对于您的样本数据,这产生了以下输出:

ID 8999 DATA "2-2-4: This was populated in no particular order"
ID 2521 DATA "30-2-8-17: Yet more sensitive Information"
ID 357  DATA "7-1-5: Sensitive Information I can't share"
ID 6002 DATA "9-30: There's a 10 behind the colon, because I hate you"

在编写这个答案时,小提琴已经失效了,但是我在MySQL Workbench中测试了这个查询,它看起来效果很好。

修改

如果要为每条记录分配新ID,可以创建一个新表(newTable),其中ID列是自动增量。然后,您可以使用INSERT INTO ... SELECT和上面的ORDER BY逻辑来填充表格。 ID字段应该由MySQL自动递增。

INSERT INTO newTable (`id`, `col`)
SELECT NULL, col
FROM yourTable
ORDER BY SUBSTRING(col, INSTR(col, '"') + 1, INSTR(col, ':') - INSTR(col, '"') - 1)

答案 1 :(得分:1)

这样的事情应该有效,但它非常微妙;在确切顺序中执行外部SELECT(*之后)必须的所有字段。 请注意,别名nl#p#r#r0除外)的计算重复...所以查询并不像最初出现的那样复杂

SELECT *
    , @r := dataOrd AS r0 -- @r is "remaining string"
    , @nextSep := INSTR(@r, '-') AS nl1
    , CAST(CASE @nextSep WHEN 0 THEN @r ELSE SUBSTR(@r, 1, @nextSep-1) END AS UNSIGNED) AS p1
    , @r := CASE @nextSep WHEN 0 THEN '' ELSE SUBSTRING(@r, @nextSep+1) END AS r1
    , @nextSep := INSTR(@r, '-') AS nl2
    , CAST(CASE @nextSep WHEN 0 THEN @r ELSE SUBSTR(@r, 1, @nextSep-1) END AS UNSIGNED) AS p2
    , @r := CASE @nextSep WHEN 0 THEN '' ELSE SUBSTRING(@r, @nextSep+1) END AS r2
    , @nextSep := INSTR(@r, '-') AS nl3
    , CAST(CASE @nextSep WHEN 0 THEN @r ELSE SUBSTR(@r, 1, @nextSep-1) END AS UNSIGNED) AS p3
    , @r := CASE @nextSep WHEN 0 THEN '' ELSE SUBSTRING(@r, @nextSep+1) END AS r3
    , @nextSep := INSTR(@r, '-') AS nl4
    , CAST(CASE @nextSep WHEN 0 THEN @r ELSE SUBSTR(@r, 1, @nextSep-1) END AS UNSIGNED) AS p4
    , @r := CASE @nextSep WHEN 0 THEN '' ELSE SUBSTRING(@r, @nextSep+1) END AS r4
FROM
(
    SELECT *, SUBSTR(`DATA`, 1, INSTR(`DATA`, ':') - 1) AS dataOrd
    FROM yourTable
) AS sepSubQ
ORDER BY p1, p2, p3, p4
;

从技术上讲,最后一个@r赋值(别名r4)是不必要的,但它完成了需要重复的模式,如果你需要处理超过4个订单"部件& #34 ;;在这种情况下,您只需要重复最后三个字段计算(增加别名)。

如果你想摆脱"工作"字段,您可以将其包装在另一个外部查询中,只选择您想要的原始表中的字段和上述查询中的pX字段;从技术上讲,您甚至不需要选择pX字段,因为此查询已经执行了订单,或者可以在包装器中完成而不选择它们。

SELECT `ID`, `DATA`
FROM ([the query above]) AS subQ
ORDER BY p1, p2, p3, p4
;