mysql按子查询顺序排序:其中a.id = b.id,按b.id排序,查询不应该订购,但确实如此

时间:2014-03-02 13:58:52

标签: mysql sql-order-by

我的目标是按距离订购结果。

我可以使用FIELD()来排序,但是使用1000的城市它看起来并不高效,而且查询变得非常大,除了我必须使用php构建查询并运行多重查询。

我在这里简化了“复杂”查询,而不是将其复杂化。

select a.id from 
(select 1 as id union select 2 as id union select 3 as id) a, 
(select 2 as id union select  3 as id union select 1 as id) b 
where  a.id  = b.id ;


Result
+----+
| id |
+----+
|  2 |
|  3 |
|  1 |
+----+

我的问题是: 1)为什么这个查询按b.id排序?这实际上就是我想要的,但我不明白为什么会这样做。

2)这个查询可以写得更有效吗?

到目前为止,我所尝试的内容无效:

select a.id from  
(select 1 as id union select 2 as id union select 3 as id) a,  
(select 2 as id union select  3 as id union select 1 as id) b  
order by  a.id  = b.id desc;

不起作用。结果:

+----+
| id |
+----+
|  1 |
|  3 |
|  1 |
|  2 |
|  2 |
|  3 |
+----+

[编辑删除了生产查询]

[编辑2个更多的例子,我似乎按b.id的选择顺序排序]

select a.id from  
(select 1 as id union select 2 as id union select 3 as id) a,  
(select  1 as id union select  2 as id union select 3 as id) b  
where  a.id  = b.id;

Result

+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
+----+


select a.id from  
(select 1 as id union select 2 as id union select 3 as id) a,  
(select  3 as id union select  2 as id union select 1 as id) b  
where  a.id  = b.id;

Result

+----+
| id |
+----+
|  3 |
|  2 |
|  1 |
+----+

[编辑4,使用时的相同排序行为:按a.id IN(b.id)排序]

 select a.id from       
(select 1 as id union select 2 as id union select 3 as id) a,       
(select  1 as id      union select  2 as id union select 3 as id) b       
where  a.id  IN ( b.id );

Result

+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
+----+

从中选择a.id.     (选择1作为id联合选择2作为id联合选择3作为id)a,
    (选择3作为id联合选择1作为id联合选择2作为id)b
    其中a.id IN(b.id);

Result

+----+
| id |
+----+
|  3 |
|  1 |
|  2 |
+----+

1 个答案:

答案 0 :(得分:0)

第一个问题的答案很简单。除非使用order by,否则SQL结果集是无序的。 (或者,在MySQL中依赖于group by所做的弃用排序。)SQL引擎可以处理数据,但它喜欢。然而产生它喜欢的结果。结果顺序是任意的。

您的第一个查询无法更有效地编写,但强烈建议使用正确的join语法:

select a.id
from  (select 1 as id union select 2 as id union select 3 as id
      ) a join
      (select 2 as id union select 3 as id union select 1 as id
      ) b  
      on a.id  = b.id;

第二个更有趣。我们来看看它:

select a.id
from  (select 1 as id union select 2 as id union select 3 as id) a,  
      (select 2 as id union select 3 as id union select 1 as id) b  
order by  a.id  = b.id desc;

你在两个数字列表之间做cross join - 使用(恐怖恐怖)隐式连接语法而不是cross join

您的order by现在的条件为a.id = b.id desc。好吧,在MySQL中,a.id = b.id成为一个布尔值,其值为1表示true,0表示false。因此,这将订购笛卡尔积,将匹配放在列表的顶部。它没有过滤