2012-06-20 13 views
6

Tôi có một bảng nói table1 có 3 cột column1, column2 and column3.LEFT OUTER JOIN và SUBSELECT trong MySQL

column1column2FOREIGN KEY với 2 bảng khác. Tuy nhiên, dữ liệu trong column3 là từ n số bảng.

Ví dụ: Hãy để chúng tôi xem xét Facebook. Để hiển thị các hoạt động, nó có thể duy trì một bảng có thể có user1 photoliked photo1 hoặc user1 statusliked status1. Vì vậy, trong trường hợp này, column3 không được là FOREIGN KEY với một bảng cụ thể.

Hiện nay có 2 cách để nhận được dữ liệu thực tế -

cách 1 -

SELECT user_id, 
     verb_id, 
     CASE WHEN verb_id = photoliked THEN 
      (SELECT photo_name FROM photos WHERE photo_id = column3) -- getting the desired data from the third column 
     WHEN verb_id = statusliked THEN 
      (SELECT status FROM statustable WHERE status_id = column3) 
     ELSE '' END AS performedon 
FROM table1 
    JOIN table2 ON user_id = user_id -- joining the first column 
    JOIN table3 ON verb_id = verb_id -- joining the second column 

2 cách -

SELECT user_id, 
     verb_id, 
     CASE WHEN verb_id = photoliked THEN 
      p.photo_name 
     WHEN verb_id = statusliked THEN 
      s.status 
     ELSE '' END AS performedon 
FROM table1 
    JOIN table2 ON user_id = user_id -- joining the first column 
    JOIN table3 ON verb_id = verb_id -- joining the second column 
    LEFT JOIN photos p ON p.photo_id = column3 -- joining the column3 with specific table 
    LEFT JOIN statustable s ON s.status_id = column3 

Câu hỏi

nào trong 2 cách tốt hơn là truy xuất dữ liệu? và truy vấn nào ít tốn kém hơn?

+0

có thể lặp lại http://stackoverflow.com/a/10684539/1239506 –

+0

Không nó không được lặp lại. Trong câu hỏi đó, có một 'IN' trong mệnh đề' WHERE' và 'SUBSELECT' không phụ thuộc vào bất kỳ cột nào của truy vấn chính. – JHS

+0

Truy vấn thứ hai tốt hơn ... –

Trả lời

1

Thứ hai sẽ nhanh hơn và lý do là người đầu tiên chứa những gì được gọi là truy vấn con tương quan. Các truy vấn phụ có mối tương quan với các bản ghi từ truy vấn chính. Vì vậy, các truy vấn con cần phải được chạy một lần cho mỗi bản ghi phù hợp trong truy vấn chính. Trong trường hợp của bạn, nó không thể chạy truy vấn phụ cho đến khi nó xác định giá trị của verb_id trong truy vấn chính. Đó là rất nhiều truy vấn để chạy.

GIẢI THÍCH về truy vấn đầu tiên sẽ cho biết vấn đề này. Nó thường là một lá cờ đỏ khi bạn nhìn thấy nó trong một GIẢI THÍCH.

1

Tôi nghĩ JOIN sẽ nhanh hơn vì nó được thực hiện một lần cho một truy vấn, và cũng có thể tôi sẽ cố gắng để lọc verb_id trong JOIN

SELECT user_id, 
    verb_id, 
    COALESCE(p.photo_name, s.status) AS performedon 
FROM table1 
    JOIN table2 ON user_id = user_id -- joining the first column 
    JOIN table3 ON verb_id = verb_id -- joining the second column 
    LEFT JOIN photos p ON verb_id = 'photoliked' AND p.photo_id = column3 -- joining the column3 with specific table 
    LEFT JOIN statustable s ON verb_id = 'statusliked' AND s.status_id = column3 
1

Bạn có thể sử dụng phương pháp này:

SELECT t.user_id, 
     t.verb_id, 
     p.photo_name AS performedon 
FROM table1 AS t 
    JOIN table2 AS t2 ON t2.user_id = t.user_id 
    JOIN table3 AS t3 ON t3.verb_id = t.verb_id 
    JOIN photos AS p ON p.photo_id = t.column3 
         AND t.verb_id = 'photoliked' 

UNION ALL 

SELECT t.user_id, 
     t.verb_id, 
     s.status 
FROM table1 AS t 
    JOIN table2 AS t2 ON t2.user_id = t.user_id 
    JOIN table3 AS t3 ON t3.verb_id = t.verb_id 
    JOIN statustable AS s ON s.status_id = t.column3 
          AND t.verb_id = 'statusliked' ;