Mysql order by subquery id : where a.id = b.id, orders by b.id , query shouldnt order, but it does

StackOverflow https://stackoverflow.com/questions/22128532

  •  19-10-2022
  •  | 
  •  

سؤال

My goal is to order results by distance.

I could use FIELD() to order by, but with 1000's of city's it does not really seem efficient, and the query grows very large, besides i have to build the query with php and run multipe queries.

In stead of putting the "complex" query here i simplified it.

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 |
+----+

My questions are: 1) Why does this query order by b.id? That is actually what i want, but i dont get why it does so.

2) Could this query be written more efficient?

What i have tried so far which does not work:

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;

Does not work. Results:

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

[EDIT removed production query]

[EDIT 2 more examples, that i seems like it is ordering by select order of 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 |
+----+

[EDIT 4, same ordering behaviour when used: order by 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 |
+----+

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 1 as id union select 2 as id) b
where a.id IN ( b.id );

Result

+----+
| id |
+----+
|  3 |
|  1 |
|  2 |
+----+
هل كانت مفيدة؟

المحلول

The answer to your first question is simple. SQL result sets are unordered unless you use order by. (Or, in MySQL rely on the deprecated ordering done by group by.) The SQL engine can process the data however it likes. And produce the results however it likes. The resulting order is arbitrary.

Your first query cannot be written more "efficiently", but proper join syntax is highly recommended:

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;

The second is more interesting. Let's look at it:

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;

You are doing a cross join between two lists of numbers -- using (horror of horrors) implicit join syntax instead of cross join.

Your order by now has the condition a.id = b.id desc. Well, in MySQL, a.id = b.id becomes a boolean, which takes on a value of 1 for true and 0 for false. So, this will order the Cartesian product, putting the matches at the top of the list. It does no filtering

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top