2011-07-03 41 views
5

Tôi đang già đi hoặc các truy vấn tôi cần viết ngày càng phức tạp hơn. Truy vấn sau sẽ nhận được tất cả các tasks liên kết với người dùng.hợp nhất hai truy vấn SELECT

"SELECT `date` 
    FROM `tasks` 
    WHERE `user_id`= 1;" 

Bảng tasks là (id, date, user_id, url_id);

Bây giờ, tôi cần phải nhận cũng ghi rằng url_id cộng sự với người sử dụng trough

`urls` table (`id`, `user_id`) 

Truy vấn độc lập sẽ trông như thế này:

"SELECT `t1`.`data` 
    FROM `tasks` `t1` 
    JOIN `urls` `u1` ON `u1`.`id` = `t1`.`url_id` 
    WHERE `u1`.user_id` = 1;" 

Mặc dù, là nó có thể kết hợp hai truy vấn này thành một truy vấn đơn lẻ? Logic của tôi nói rằng nó nên được, mặc dù tôi không thấy làm thế nào để làm JOIN thực tế.

+0

Ý của bạn là 'dữ liệu' hoặc' ngày' trong truy vấn cuối cùng của bạn? Ngoài ra, nếu bạn không chọn bất kỳ dữ liệu nào từ bảng URL, bạn có thực sự cần tham gia không? (Câu trả lời có thể là "có, để đảm bảo rằng có một mục nhập URL cho ID người dùng đó".) Và tại sao lại có rất nhiều dấu tích; nó là xấu như MS SQL Server và dấu ngoặc vuông! –

+0

Tôi đã viết truy vấn trên đường, vì vậy tôi tự nhiên để lại một vài sai lầm. Bạn nói đúng, nó phải là 'ngày' không phải' dữ liệu'. Tôi thường bỏ qua một nhận xét về 'back-ticks', mặc dù bạn có danh tiếng khá cao, vì vậy tôi kinda tò mò tại sao bạn đang nói rằng "nó là xấu như MS SQL Server và dấu ngoặc vuông"? Mục đích chính của backticks là để đảm bảo rằng máy chủ MySQL có thể nhanh chóng xác định tên bảng và cột và để tránh nhầm lẫn khi sử dụng từ khóa dành riêng, như 'left' hoặc' right' trong bộ lồng nhau. – Gajus

+0

Yêu cầu tương tự được thực hiện cho các dấu ngoặc vuông của người dùng MS SQL Server. Nó trông xấu xí với tôi và nó hoàn toàn phi tiêu chuẩn. Không có DBMS nào khác hỗ trợ các dấu back-tick hoặc dấu ngoặc vuông cho những gì mà chuẩn SQL gọi là các định danh phân định giới hạn, mà tiêu chuẩn nói được kèm theo trong dấu ngoặc kép; dấu nháy đơn được dành riêng cho chuỗi. DBMS khác nhau có các quy tắc khác nhau cho nơi bạn có thể sử dụng từ khóa. Cái tôi sử dụng chủ yếu cho phép từ khóa là số nhận dạng ở nhiều nơi. Tốt nhất là tránh các dấu ngoặc kép bằng cách tránh các từ khóa dưới dạng số nhận dạng. –

Trả lời

5

Tôi có thể sử dụng UNION.

SELECT `date` 
    FROM `tasks` WHERE `user_id`=1 
UNION 
SELECT `t1`.`date` 
    FROM `tasks` `t1` 
    INNER JOIN `urls` `u1` ON `u1`.`id` = `t1`.`url_id` 
    WHERE `u1`.user_id`=1; 
+0

Lưu ý rằng bạn sẽ muốn 'UNION ALL' nếu bạn không muốn các bản sao bị xóa. – tvanfosson

+0

Điều đó thật kỳ lạ. Tôi đã không bao giờ sử dụng UNION trước đây trong cuộc sống của tôi và đây là lần thứ ba trong hai ngày qua. :) Mặc dù, cảm ơn bạn! – Gajus

+0

@Guy - bạn được chào đón, nhưng tôi tự hỏi tại sao không upvote? :-( – tvanfosson

1

Bạn có thể làm điều này trong một truy vấn duy nhất:

SELECT t.date 
    FROM TASKS t 
WHERE t.user_id = 1 
    OR EXISTS(SELECT NULL 
       FROM URLS u 
       WHERE u.id = t.url_id 
       AND u.user_id = 1) 

Tuy nhiên, OR là một nghệ sĩ nổi tiếng là xấu - nó mảnh vụn kế hoạch thực hiện. Việc tách truy vấn, việc kết hợp các bộ kết quả có thể được thực hiện bằng cách sử dụng các toán tử UNION hoặc UNION ALL. UNION xóa các bản sao khỏi tập kết quả cuối cùng; UNION ALL không loại bỏ trùng lặp và nhanh hơn.

SELECT t.date 
    FROM TASKS t 
WHERE t.user_id = 1 
UNION ALL 
SELECT t.date 
    FROM TASKS t 
WHERE EXISTS(SELECT NULL 
       FROM URLS u 
       WHERE u.id = t.url_id 
       AND u.user_id = 1) 

Biết dữ liệu của bạn để bạn biết nhà cung cấp dịch vụ nào tốt nhất đáp ứng nhu cầu của bạn.

Các vấn đề liên quan