Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL Left Join Subquery with *

I'm putting together a fairly simple query with a subquery in the JOIN statement. It only works if I include an * in the subquery select. Why?

This works

$sql = 'SELECT locations.id, title, name, hours.lobby
        FROM locations
        LEFT JOIN states ON states.id = locations.state_id
        LEFT JOIN (SELECT *, type_id IS NOT NULL AS lobby FROM location_hours) AS hours ON locations.id = hours.location_id
        GROUP BY locations.id';

This doesn't

$sql = 'SELECT locations.id, title, name, hours.lobby
        FROM locations
        LEFT JOIN states ON states.id = locations.state_id
        LEFT JOIN (SELECT type_id IS NOT NULL AS lobby FROM location_hours) AS hours ON locations.id = hours.location_id
        GROUP BY locations.id';

Should I even be doing it this way? I thought * was not best if you don't need all the fields?

like image 562
MAZUMA Avatar asked Oct 23 '13 23:10

MAZUMA


People also ask

How do I JOIN a sub query in MySQL?

A subquery is usually added within the WHERE Clause of another SQL SELECT statement. You can use the comparison operators, such as >, <, or =. The comparison operator can also be a multiple-row operator, such as IN, ANY, SOME, or ALL.

Can we use subquery in joins?

Subqueries can be used as an alternative to joins. A subquery is typically nested inside the WHERE clause. Subqueries must always be enclosed within parentheses. The table that's specified in the subquery is typically different than the one in the outer query, but it can be the same.

IS LEFT JOIN better than subquery?

Conclusion : A subquery is easier to write, but a joint might be better optimized by the server. For example a Left Outer join typically works faster because servers optimize it.

What is MySQL left JOIN?

The Left Join in MySQL is used to query records from multiple tables. This clause is similar to the Inner Join clause that can be used with a SELECT statement immediately after the FROM keyword.


1 Answers

try this (if I understood your intent correctly, that you wanted to filter on type_id not null):

   SELECT locations.id, title, name, hours.lobby
     FROM locations
LEFT JOIN states
       ON states.id = locations.state_id
LEFT JOIN (SELECT location_id, type_id AS lobby
             FROM location_hours 
            WHERE type_id IS NOT NULL) AS hours
       ON locations.id = hours.location_id
 GROUP BY locations.id';

The explanation is that you have to select in the inner query all the fields which are referenced in the outer query.

like image 87
Ashalynd Avatar answered Sep 28 '22 08:09

Ashalynd