2013-05-06 55 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();