【问题标题】:Mysql order by subquery id : where a.id = b.id, orders by b.id , query shouldnt order, but it doesMysql order by subquery id : where a.id = b.id, orders by b.id , query should not order, but it does
【发布时间】:2014-03-02 13:58:52
【问题描述】:

我的目标是按距离排序结果。

我可以使用 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 union 选择 2 作为 id union 选择 3 作为 id) a,
(选择 3 作为 id union 选择 1 作为 id union 选择 2 作为 id) b
其中 a.id IN ( b.id );

Result

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

【问题讨论】:

    标签: mysql sql-order-by


    【解决方案1】:

    第一个问题的答案很简单。 SQL 结果集是无序的,除非您使用order by。 (或者,在 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 为真,0 为假。因此,这将订购笛卡尔积,将匹配项放在列表的顶部。它没有过滤

    【讨论】:

    • 感谢您的回复。对于你写的第一个查询:“并产生它喜欢的结果。”。奇怪的是,它没有。它返回按 b.id 的选择顺序排序的结果。我理解第二个答案,谢谢,这不是我要走的路。您对以有效的方式完成我想要的事情有什么建议吗?我应该这样回应吗?还是我应该编辑原始问题?
    • 非常抱歉,我有点困惑。你的意思是这两个查询都不会实现按 b.id 排序结果?
    • 只有在查询中有order by b.id时才会得到想要的订单。
    • 它只在我使用时按需要工作:order by a.id=b.id。但是因为我不知道我会接受你的回答是什么。谢谢。
    猜你喜欢
    • 2013-07-07
    • 2015-02-26
    • 2022-12-01
    • 1970-01-01
    • 2015-04-11
    • 2012-01-09
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多