2016-07-27 111 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 
; 
相關問題