引用同一查询中的查询中已经获取的结果

时间:2013-05-06 21:39:42

标签: mysql sql select sql-order-by

假设我有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 个答案:

答案 0 :(得分: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();