2013-05-06 53 views
0

因此,假設我有這個表4列:在同一查詢中涉及到已經獲取的成果在查詢

id content parent timestamp 

藉此父列是指在表中的另一個條目的ID

我要做到以下幾點:

從以下有序表中選擇第50行:

for each row, 

if(parent = 0){ 
    add row to resultset, ordered by timestamp 
} 
else if (parent != 0){ 
    if parent is in the list of rows already fetched so far by the query, 
    add row to resultset, ordered by the timestamp 
    otherwise, wait until the parent gets fetched by the query 
    (assuming it gets fetched at all since there we're only getting the first 50 rows) 
} 

這種排序邏輯有點複雜,我想知道是否可以在單個查詢中使用MYSQL ORDER BY語句完成此操作,而無需使用子查詢?也許我們可以設置和使用變量?但是,ORDER BY聲明將如何實施?

+1

我敢肯定,這是不可能的'訂單'並且相當困難,即使子查詢。從樹結構中提取子樹將具有相似的僞代碼。而且,提取子樹是一個難題。 – 2013-05-06 21:54:03

+0

是一對一的父母孩子嗎?它只有一個深度? – mconlin 2013-05-06 23:45:35

回答

0

這是一個使用變量的解決方案,我使用一個外連接和一個臨時表來存放未使用的輸入數據但沒有子查詢的循環。

刪除所有舊版本的程序和設置分隔符

DROP PROCEDURE IF EXISTS order_proc; 
DELIMITER ;; 

開始編寫程序時

CREATE PROCEDURE order_proc() 
BEGIN 
DECLARE n INT DEFAULT 50; 
DECLARE m INT DEFAULT 0; 
DECLARE i INT DEFAULT 0; 
DECLARE custom_limit INT DEFAULT 0; 

DROP TABLE IF EXISTS pre_resultset; 
CREATE TABLE pre_resultset LIKE input_data; 
ALTER TABLE pre_resultset MODIFY id INT; 
ALTER TABLE pre_resultset DROP PRIMARY KEY; 
ALTER TABLE pre_resultset ADD COLUMN iid INT PRIMARY KEY NOT NULL AUTO_INCREMENT FIRST; 

SELECT n INTO custom_limit; 
Set SQL_SELECT_LIMIT = custom_limit; 
INSERT INTO pre_resultset SELECT NULL,id, content, parent, timestamp FROM input_data WHERE parent = 0 ORDER BY timestamp; 
Set SQL_SELECT_LIMIT = default; 

DROP TABLE IF EXISTS unused_input_data; 
CREATE TABLE unused_input_data LIKE input_data; 
ALTER TABLE unused_input_data ADD null_col VARCHAR(1); 
SELECT COUNT(*) FROM pre_resultset INTO m; 
WHILE m<n DO 
    SELECT COUNT(*) FROM pre_resultset INTO m; 
    TRUNCATE unused_input_data; 
    INSERT INTO unused_input_data SELECT input_data.id, input_data.content, input_data.parent, input_data.timestamp, pre_resultset.id AS null_col FROM input_data LEFT OUTER JOIN pre_resultset on input_data.id = pre_resultset.id WHERE pre_resultset.id IS NULL ; 

    SELECT n-m INTO custom_limit; 
    Set SQL_SELECT_LIMIT = custom_limit; 
    INSERT INTO pre_resultset SELECT NULL, unused_input_data.id, unused_input_data.content, unused_input_data.parent, unused_input_data.timestamp FROM unused_input_data JOIN pre_resultset WHERE unused_input_data.parent = pre_resultset.id ORDER BY unused_input_data.timestamp; 
    Set SQL_SELECT_LIMIT = default; 

    SELECT COUNT(*) FROM pre_resultset INTO i; 
    SELECT (IF(i = m, n, i)) INTO m; 
END WHILE; 
SELECT id, content, parent, timestamp FROM pre_resultset AS resultset; 
DROP TABLE IF EXISTS pre_resultset; 
DROP TABLE IF EXISTS unused_input_data; 
End; 
;; 

更改分隔符回

DELIMITER ; 

運行過程

CALL order_proc();