2013-10-23 14 views
5

Tôi đang đặt cùng một truy vấn khá đơn giản với truy vấn phụ trong câu lệnh JOIN. Nó chỉ hoạt động nếu tôi bao gồm một * trong truy vấn con chọn. Tại sao?MySQL Left Join Subquery với *

này hoạt động

$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'; 

này không

$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'; 

nên tôi thậm chí được làm việc đó theo cách này? Tôi nghĩ rằng * không phải là tốt nhất nếu bạn không cần tất cả các lĩnh vực?

Trả lời

20

thử loại này (nếu tôi hiểu ý định của bạn một cách chính xác, mà bạn muốn lọc trên type_id không null):

$sql = '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'; 

Lời giải thích là bạn phải chọn trong truy vấn bên trong tất cả các lĩnh vực mà được tham chiếu trong truy vấn bên ngoài.

+1

vấn đề của bạn khi bạn chỉ chọn một trường từ truy vấn phụ của bạn là bạn không thể thực hiện câu lệnh nối, vì hours.location_id không được cung cấp bởi truy vấn con nếu bạn chỉ chọn type_id. – Ashalynd

+0

Điều đó có ý nghĩa. Và rõ ràng là tôi cho là vậy. Dù sao thì nó cũng hoạt động. Cảm ơn bạn. – MAZUMA

+0

Ngoài ra kiểm tra xem bạn có thực sự cần phải sử dụng (trong trường hợp thứ hai) LEFT JOIN thay vì JOIN. Nếu bạn không muốn NULL type_id sau đó tôi giả sử bạn thực sự có thể muốn chạy một JOIN (thường là nhanh hơn). – Ashalynd

0

Vì bạn muốn có giá trị không NULL cho type_id, bạn không nên sử dụng LEFT JOIN cho nó. Bạn sẽ muốn những điều sau, sử dụng JOIN chuẩn.

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

Toàn bộ điểm của JOIN là chỉ tham gia các hàng thực sự tồn tại. Vì vậy, bạn sẽ không nhận được bất kỳ hàng nào mà location_hours không có location_id tương ứng với locations.id. Sau đó, bạn chỉ lọc ra các giá trị NULL cho location_hours.type_id.

+0

Nếu tôi chỉ chạy một tham gia, chỉ có các hàng vị trí. Tôi muốn tất cả các hàng vị trí. Sau đó tôi muốn xem nếu giờ đã được thiết lập cho những địa điểm mua xem có hay không có một giá trị NULL. – MAZUMA

+0

Tôi không chắc chắn nếu tôi hiểu những gì bạn có ý nghĩa. Bạn có thể rephrase nó? Ngoài ra, lý do tại sao LEFT JOIN của bạn không hoạt động là vì truy vấn phụ không chọn location_id nhưng bạn đang sử dụng nó cho điều kiện ON. – Chill

+0

Nếu tôi chạy JOIN, nó sẽ loại trừ các hàng không tồn tại type_id. Tôi muốn nhận tất cả các hàng vị trí và sau đó xem liệu có giá trị cho type_id cho từng vị trí hay không. Tôi đang sử dụng giá trị đó để xác định có cần thêm hoặc chỉnh sửa giờ cho vị trí cụ thể đó hay không. – MAZUMA