我有两张桌子:
1)profiles
+----+---------+
| id | name |
+----+---------+
| 1 | WILLIAM |
| 2 | JOHN |
| 3 | ROBERT |
| 4 | MICHAEL |
| 5 | JAMES |
| 6 | DAVID |
| 7 | RICHARD |
| 8 | CHARLES |
| 9 | JOSEPH |
| 10 | THOMAS |
+----+---------+
2)request_for_friendship
+----+---------+-------+
| id | from_id | to_id |
+----+---------+-------+
| 1 | 1 | 2 |
| 2 | 1 | 3 |
| 3 | 1 | 8 |
| 5 | 4 | 1 |
| 6 | 9 | 1 |
+----+---------+-------+
我需要对所有profiles
进行一些排序,然后将其加入request_for_friendship
例如,让所有用户进行一些排序:
mysql> SELECT *
-> FROM profiles
-> ORDER BY name ASC;
+----+---------+
| id | name |
+----+---------+
| 8 | CHARLES |
| 6 | DAVID |
| 5 | JAMES |
| 2 | JOHN |
| 9 | JOSEPH |
| 4 | MICHAEL |
| 7 | RICHARD |
| 3 | ROBERT |
| 10 | THOMAS |
| 1 | WILLIAM | <-- WILLIAM IS LAST!
+----+---------+
一切看起来都很好,排序存在。之后我加入了request_for_friendship
,我的sotring将会休息:
mysql> SELECT * FROM
-> (
-> SELECT *
-> FROM profiles
-> ORDER BY name ASC
-> ) as users
-> LEFT JOIN request_for_friendship
-> AS request_for_friendship_copy
-> ON
-> (
-> request_for_friendship_copy.from_id = 1
-> AND
-> request_for_friendship_copy.to_id = users.id
-> )
-> OR
-> (
-> request_for_friendship_copy.from_id = users.id
-> AND
-> request_for_friendship_copy.to_id = 1
-> );
+----+---------+------+---------+-------+
| id | name | id | from_id | to_id |
+----+---------+------+---------+-------+
| 2 | JOHN | 1 | 1 | 2 |
| 3 | ROBERT | 2 | 1 | 3 |
| 8 | CHARLES | 3 | 1 | 8 |
| 4 | MICHAEL | 5 | 4 | 1 |
| 9 | JOSEPH | 6 | 9 | 1 |
| 1 | WILLIAM | NULL | NULL | NULL | <-- WILLIAM IN THE MIDDLE!
| 5 | JAMES | NULL | NULL | NULL |
| 6 | DAVID | NULL | NULL | NULL |
| 7 | RICHARD | NULL | NULL | NULL |
| 10 | THOMAS | NULL | NULL | NULL |
+----+---------+------+---------+-------+
如何JOIN LEFT
原始排序保存?
我无法对 JOIN LEFT
之后的结果进行排序,因为ORDER BY
JOIN
在我的数据库中需要~0.02s 1}} strong>(约1 000 000位用户)但是当ORDER BY
JOIN
//Revrse an array
import java.util.*;
public class ReverseSecond
{
static int revArray(int []d)
{
int temp=0;
for(int i=0;i<d.length/2;i++)
{
temp=d[i];
d[i]=d[d.length-1-i];
d[d.length-1-i]=temp;
}
return d;
}
public static void main(String h[])
{
int no[]={10,20,30,40,50};
System.out.println("Before Reverse:-");
for(int i=0;i<no.length;i++)
{
System.out.println(""+no[i]);
}
System.out.println("Reverse Array is :-"+revArray(no));
}
}
后需要大约3.2秒时,这是非常大的时间:(
Demo: http://sqlfiddle.com/#!9/167792/1
以sqlfiddle顺序保存!但是怎么样? MySQL 5.6保存了订单?
答案 0 :(得分:2)
(解释失去ORDER BY
)
SQL标准基本上说子查询是一组无序的行。这意味着优化工具可以自由地忽略“派生”表中的ORDER BY
:FROM ( SELECT ... ORDER BY )
。在MySQL和MariaDB的“最新”版本中,正在删除此类ORDER BYs
。在其他情况下,忽略ORDER BY
。
在某些情况下(不确定此情况),在LIMIT 99999999
诱骗优化程序执行ORDER BY
之后添加ORDER BY
(大号) 。但是,它仍然可以在以后忽略“订单”。
MySQL的一般规则:避免使用子查询。 (有些情况下子查询更快,但不是你的。)
强有力的规则:如果您希望对结果进行排序,那么必须在最外面有ORDER BY
。
如果您在第一个查询中将LIMIT 3
添加到派生表中,则只能获得CHARLES,DAVID,JAMES,,但不一定按此顺序。也就是说,你需要两个ORDER BYs
- 派生表中的一个,最后一个。
答案 1 :(得分:0)
试试这个:
SELECT
a.name as `from_name`,
IFNULL(GROUP_CONCAT(b.name),'-none-') as `to_name`,
IFNULL(c.from_id,'-none-') as `from_id`,
IFNULL(GROUP_CONCAT(c.to_id),'-none-') as `to_id`
FROM profiles a
LEFT JOIN request_for_friendship c
ON a.id = c.from_id
LEFT JOIN profiles b
ON c.to_id = b.id
GROUP BY a.name
ORDER BY a.name,b.name
或者,如果你想要每行#34;来自&#34;名:
this
答案 2 :(得分:0)
SELECT *
FROM profiles p
LEFT
JOIN request_for_friendship r
ON (r.from_id = p.id AND r.to_id = 1)
OR (r.from_id = 1 AND r.to_id = p.id)
ORDER
BY name;
+----+---------+------+---------+-------+
| id | name | id | from_id | to_id |
+----+---------+------+---------+-------+
| 8 | CHARLES | 3 | 1 | 8 |
| 6 | DAVID | NULL | NULL | NULL |
| 5 | JAMES | NULL | NULL | NULL |
| 2 | JOHN | 1 | 1 | 2 |
| 9 | JOSEPH | 6 | 9 | 1 |
| 4 | MICHAEL | 5 | 4 | 1 |
| 7 | RICHARD | NULL | NULL | NULL |
| 3 | ROBERT | 2 | 1 | 3 |
| 10 | THOMAS | NULL | NULL | NULL |
| 1 | WILLIAM | NULL | NULL | NULL |
+----+---------+------+---------+-------+
10 rows in set (0.02 sec)
mysql>
答案 3 :(得分:0)
我知道这个问题已经有两年了,但是我没有找到这个可能的解决方案。对于我来说,这是使子查询结果保持正确顺序最有效的解决方案。
请考虑在您的子查询中添加“行号”。然后在row_number上使用ORDER BY。
这说明了如何添加row_number: select increment counter in mysql
就我而言,在层次结构递归查询中可能存在的行数未知,我需要保持子查询的顺序结果在外部查询中保持不变。
这是我的查询
SELECT l.row_number, l.userid, l.child, p.id, p.username
FROM (
SELECT @rownum := @rownum + 1 AS row_number, u.parent AS userid, _id AS child
FROM (
SELECT @r AS _id, (SELECT @r := parent FROM new_clean WHERE userid = _id) AS parent
FROM (SELECT @r := ?) AS vars, new_clean h
WHERE @r <> 0
) u
CROSS JOIN (SELECT @rownum := 0) r
WHERE u.parent <> 0
) l
LEFT JOIN profile p ON p.userid = l.userid
ORDER BY row_number