2016-08-30 44 views
3

我有一個這樣的表值:的MySQL SELECT命令由2列

CREATE TABLE rows(
    UniqueID VARCHAR(225), 
    Previous VARCHAR(225), 
    Next VARCHAR(225) 
); 

有了內容,看起來像這樣:

+----------+-----------+-----------+ 
| UniqueID | Previous | Next  | 
+----------+-----------+-----------+ 
| 676 | undefined |  219 | 
| 890 |  219 | undefined | 
| 219 |  676 |  890 | 
+----------+-----------+-----------+ 

正如你所看到的,行有UID的,其中PreviousNext列是指。

我現在想要的是,編寫一個SELECT *語句,它會對PreviousNext字段中的所有結果進行排序。 undefined值標記結束元素。我怎麼能做到這一點?在上面顯示的表格中,我想要的順序是顯示那裏的內容,最後2個行位置交換,因此行X的Next指向Y行的UID,它具有指向UID的Previous該行的X.等

+3

請以前添加的預期結果 –

+0

'秩序,next'? – Jens

+0

未定義元素如何排序? –

回答

2

你試圖創建的是一個遞歸查詢。不幸的是,MySQL並沒有這麼簡單。如果父母的索引總是比孩子多,那麼有相對簡單的解決方案,但這裏並不是這樣。討論這類問題有幾個問題。以下問題的答案探索了嘗試此類查詢的各種方法,包括使用存儲過程。

How to do the Recursive SELECT query in MySQL?

與存儲過程的想法去,你可以嘗試像:

CREATE PROCEDURE getInOrder() 
    BEGIN 
    DECLARE child_id VARCHAR(256); 
    DECLARE prev_id VARCHAR(256); 
    SELECT UniqueID INTO prev_id FROM rows WHERE Previous = 'undefined'; 
    SELECT `Next` INTO child_id 
    FROM rows WHERE UniqueID = prev_id; 
    CREATE TEMPORARY TABLE IF NOT EXISTS temp_table AS (SELECT * FROM rows WHERE 1=0); 
    TRUNCATE TABLE temp_table; 
    WHILE child_id <> 'undefined' DO 
     INSERT INTO temp_table SELECT * FROM rows WHERE UniqueID = prev_id; 
     SET prev_id = child_id; 
     SELECT `Next` INTO child_id 
     FROM rows WHERE UniqueID = prev_id; 
    END WHILE; 
    INSERT INTO temp_table SELECT * FROM rows WHERE UniqueID = prev_id; 
    SELECT * FROM temp_table; 
    END; 

然後,您可以調用存儲過程來檢索順序表。

工作例如:http://sqlfiddle.com/#!9/085dec/2

+0

Hey @Surberus,我目前正在使用你的方法,但是我開始注意到,只有一行在表中,整個過程只是掛起。有沒有可用的解決方法,只會在這種情況下返回該行? –

+0

嗨@RandoHinn。如果表沒有合格的數據,存儲過程將掛起。下面的小提示表明,只要該行的'Previous'和'Next'設置爲'undefined',該過程就可以使用一行。 http://sqlfiddle.com/#!9/40317/1 while循環要求最終提供一行,其中'Next'是未定義的,否則它將永遠循環。 您可以放置​​一個安全計數器,以確保您循環的次數不會超過表格中的行數。這也可以防止一組循環進入的數據。 – Surberus

+0

嘿,@Surberus現在將Previous和Next設置爲'undefined'。仍然掛起..當表是空的,它有效,當它有1行時,它掛起..:/ –

0
ORDER BY IFNULL(prev, ''),   -- some value lower than the rest 
     IFNULL(next, 'zzzzz')  -- some value higher than all values 

(從技術上講,第一部分可以僅僅是prev,沒有IFNULL)。

如果ID真的數字,你應該使用數字類型,如INT UNSIGNED 。如果他們真的是字符串,你需要225嗎?

這是假設prev <下一步 - 是否必然如此?似乎任意鏈接可能不會保留這一點。如果您需要查看next以基於UniqueId加載下一行,則代碼要複雜得多。

0

我認爲這個要求缺乏細節。

但是,你想最終的結果是這樣嗎?

+----------+-----------+-----------+ 
| UniqueID | Previous | Next  | 
+----------+-----------+-----------+ 
| 676 | undefined |  219 | 
| 219 |  676 |  890 | 
| 890 |  219 | undefined | 
+----------+-----------+-----------+ 

如果我是正確的,你可以用(我命名的表爲demo)實現它:

SELECT d.* FROM (
    SELECT UniqueID, IF(Previous IS NULL, -1, Previous) AS Previous, IF(Next IS NULL, 999999999999, Next) as Next 
    FROM demo 
)t 
JOIN demo d ON d.UniqueID = t.UniqueID 
ORDER BY t.Next, t.Previous 
; 

所以,當PreviousNULL你把它與-1,以確保他的是列表中的第一個,當NextNULL時,爲了確保它將成爲列表中的最後一個,請將其設置爲非常高的值,然後您只需按PreviousNext來排序查詢。

我必須強調,這個解決方案專注於提供的數據。