Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL using Inner joins on an alias of a calculated column

I have a query like so:

SELECT User.id, 10*10 as distance
FROM USERS
INNER JOIN
(
    SELECT Location.user_id,
    min(10 * 10) as mindistance
    FROM Location
    GROUP BY Location.user_id
 ) L ON Users.id = Location.user_id AND distance = L.mindistance

If I leave it as is, I keep getting:

Unknown column 'distance' in 'on clause'

But if I put User.distance instead of just distance, I get:

MySQL syntax error near....

Can I not use alias' this way on a calculated field? The 10 * 10 is just a simple placeholder as the calculation is much more complex.

like image 452
cdub Avatar asked Jul 27 '12 09:07

cdub


People also ask

Can you join by column alias?

No, you cannot do that. The alias is not bound until later in the processing. You can use "Nombre" in an ORDER BY, but not in a WHERE clause and certainly not in a JOIN clause.

Does inner join come before or after WHERE?

The where clause will be executed before the join so that it doesn't join unnecessary records.

Does inner join order matter for performance?

Basically, join order DOES matter because if we can join two tables that will reduce the number of rows needed to be processed by subsequent steps, then our performance will improve.

Does inner join need a WHERE clause?

INNER JOIN ON vs WHERE clause Linking between two or more tables should be done using an INNER JOIN ON clause but filtering on individual data elements should be done with WHERE clause. INNER JOIN is ANSI syntax whereas the WHERE syntax is more relational model oriented.


2 Answers

To avoid having to make the calculation three times in the query, you can wrap the outer calculation in a FROM subselect, which will give you access to the aliased field name (where it wasn't accessible in your original query):

SELECT a.*
FROM
(
    SELECT id, 10*10 AS distance
    FROM USERS
) a
INNER JOIN
(
    SELECT user_id,
    MIN(10 * 10) AS mindistance
    FROM Location
    GROUP BY user_id
) L ON a.id = L.user_id AND a.distance = L.mindistance

Here, the calculation is only done two times instead of three.

like image 177
Zane Bien Avatar answered Oct 05 '22 19:10

Zane Bien


You can't used derived values in a query where clause - where is used to restrict records and which indexes to use - derived values can't be used by the optimizer so you need to filter the final results.

not quite sure what you're doing but try something like:

SELECT User.id, 10*10 as distance 
FROM USERS 
INNER JOIN 
( 
    SELECT Location.user_id, 
    min(10 * 10) as mindistance 
    FROM Location 
    GROUP BY Location.user_id 
) L ON User.id = Location.user
HAVING USERS.distance = L.mindistance
like image 23
Ian Wood Avatar answered Oct 05 '22 18:10

Ian Wood