2012-11-15 38 views
5

Tôi có một bảng các hạng mục tài sản, và một bảng user_favorites có cấu trúc như thế này:MySQL - một subquery và một ĐÂU TRÊN

  • id
  • item_id
  • user_id
  • yêu thích (bool)

Khi người dùng "yêu thích" mục, nó thêm hàng vào bảng này bằng id mục, id người dùng và đặt thuộc tính yêu thích thành 1 (nếu họ "không thích e "nó được đổi thành 0).

Tôi đang cố gắng tìm hiểu cách hiển thị các mục yêu thích của người dùng khi họ xem danh sách sản phẩm.

Tôi hiện đang thực hiện truy vấn dựa trên đầu vào tìm kiếm của người dùng và nhận được một mảng ID sản phẩm. Bây giờ tôi muốn làm một truy vấn trong số các sản phẩm đó để tạo ra một bảng thông tin sản phẩm - và tôi muốn nó bao gồm có hay không mục đó là một yêu thích của người dùng.

Tôi đã thử một cái gì đó như thế này:

select i.tid, i.name as name, i.image as image, (SELECT favorite FROM user_favorites WHERE user_id=77) as favorite 
    FROM items i 

    left join user_favorites ufav on (ufav.item_id = i.tid) 
    WHERE i.tid IN (79, 98, 105 . . .) 
    order by favorite DESC, name ASC 

..nhưng tất nhiên tôi nhận được một Subquery trả hơn 1 hàng lỗi

Tôi cũng đã thử một cái gì đó như thế này:

select i.tid, i.name as name, i.image as image, ufav.favorite as favorite 
    FROM items i 
    left join user_favorites ufav on (ufav.item_id = i.tid) 
    WHERE i.tid IN (79, 98, 105 . . .) AND ufav.user_id=77 
    order by favorite DESC, name ASC 

. . . nhưng điều này chỉ trả về các mục được ưu tiên (như bạn mong đợi). Tôi muốn trả lại tất cả các mục trong danh sách ID, nhưng tôi cũng muốn biết mục nào chưa được "ưa thích".

Tôi có thể thực hiện việc này trong một truy vấn hay là tùy chọn tốt nhất để chạy hai truy vấn riêng biệt?

Trả lời

0

Đây là cách tiếp cận tôi đã kết thúc:

(
    SELECT i.tid, i.name as name, i.image, 1 AS favorite 
    FROM items i 
    LEFT JOIN user_favorites ufav on (ufav.item_id = i.tid) 
    WHERE ufav.user_id = //the user id 
    AND i.tid IN (79, 98, 105 . . .) 
) 

UNION DISTINCT 

(
    SELECT i.tid, i.name as name, i.image as image, 0 AS favorite 
    FROM items i 
    WHERE NOT EXISTS (SELECT * 
         FROM user_favorites ufav 
         WHERE ufav.item_id = i.tid 
         AND ufav.user_id = //the user id 
         AND ufav.favorite=1 
         ) 
    AND i.tid IN (79, 98, 105 . . .) 
) 
    ORDER BY favorite DESC , i.name ASC 

có vấn đề gì với điều này không? Có vẻ như tôi đang hy vọng, cho đến nay ...

1

Hãy thử điều này ::

select 
i.tid, 
i.name as name, 
i.image as image, 
ifnull(favorite,false) as isFavorite 

FROM items i 
left join user_favorites ufav on (ufav.item_id = i.tid) 
WHERE i.tid IN (79, 98, 105 . . .) and ufav.user_id=77 
    order by favorite DESC, name ASC 
+0

Cảm ơn bạn đã trả lời Sashi, nhưng John Woo là chính xác: Tôi cũng cần các mục không được ưa thích để hiển thị trong kết quả. – Zarwell

1

Tôi nghĩ rằng bạn cần phải sử dụng CROSS JOIN ở đây vì bạn muốn hiển thị tất cả các mục để tất cả người dùng, ví dụ

SELECT d.item_ID, d.Itemname, d.user_ID, 
     COALESCE(c.`favorite`, 0) Favorite 
FROM 
     (
      SELECT a.item_ID, a.Itemname, b.user_ID 
      FROM  items a CROSS JOIN 
        (
         SELECT DISTINCT user_ID 
         FROM user_favorites 
        ) b 
     ) d LEFT JOIN user_favorites c 
      ON c.item_ID = d.item_ID AND 
       c.user_ID = d.user_ID 
-- WHERE d.user_ID = 1  -- this is you condition 
ORDER BY d.user_ID, d.Item_ID 
+0

Tuyệt vời - cảm ơn rất nhiều! Tôi sẽ phải nghiên cứu điều này để tìm ra những gì đang xảy ra nhưng nó hoạt động hoàn hảo. – Zarwell

+0

Điều này dường như đang hoạt động trong quá trình thử nghiệm của tôi theo ID người dùng của riêng tôi nhưng không phải khi tôi sử dụng một ID khác. Cuối cùng tôi nhận ra nó chỉ hoạt động nếu người dùng đã "ưa thích" ít nhất một mục (vì vậy họ có một hàng trong bảng user_favorites). Nói cách khác, nếu người dùng không ưa thích một mục thì kết quả không được trả về. Bất cứ lời khuyên nào về cách để giải quyết vấn đề này? – Zarwell

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