2016-07-27 109 views
2

这是一个噩梦。我正在为现有数据库的前端工作,并且我不得不跳过这些数据库以确保数据以正确的顺序显示。如果我可以通过Id命令,它会使我的生活变得更加简单,但是Ids与数据几乎没有关系。通过字符串中的数字排序现有数据库

这里就是我的意思

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-2-1,1-1-50之后。

就像我在开始时所说的,我是一个前端人,所以在MySql中执行的东西比我能做的更多。任何帮助将非常感激。

编辑:我刚才意识到有一个单独的表中指向这个外键,使事情变得更糟。

+0

今天提示:预期结果中的数据与示例表格数据中的数据相同。 – jarlh

+0

已记录。试图开车回家是如何搅乱一切的。 – UIDAlexD

+0

我不明白结果集中“id”列的用途。 – Strawberry

回答

1

尝试此查询:

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

ORDER BY子句中的SUBSTRING(...)期限从文本中提取不仅仅是IDS。想必他们希望他们从左到右按数字排序。尽管它们是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给每个记录,您创建了一个ID列是自动增量的新表(newTable)。然后,您可以使用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) 
+0

任何基于订单分配新ID的方法? – UIDAlexD

+0

@UIDAlexD由于您应该避免使用此表来支持标准化的东西,所以我建议将您的数据插入一个新表并在此过程中分配一个数字ID。 –

+0

不是最佳的,但它看起来会很好。最后一个问题是外键。对不起,我在发布之前忘了提及。 – UIDAlexD

1

像这样的事情应该工作,但它是非常细腻;所有在SELECT(在*)必须之外的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排序“零件”的格局;在这种情况下,您只需重复最后三个字段计算(使用增加的别名)。

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

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