MySQL - 子查询和WHERE IN

时间:2012-11-15 05:02:33

标签: mysql sql

我有一个项目属性表,以及一个user_favorites表,结构如下:

  • ID
  • ITEM_ID
  • USER_ID
  • 最爱(布尔)

当用户“收藏”某个项目时,它会使用项目ID,用户ID为此表添加一行,并将favorite属性设置为1(如果他们“不喜欢”,则将其更改为0)。

我正试图弄清楚如何在用户查看产品列表时显示用户的收藏夹。

我目前根据用户搜索输入进行查询,并获取一系列产品ID。现在我想在这些产品中进行查询以创建产品信息表 - 我希望它包括该项目是否是用户最喜欢的。

我尝试过这样的事情:

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

..但当然我得到子查询返回超过1行错误

我也尝试过这样的事情:

   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

。 。 。但这只返回被收藏的项目(正如您所期望的那样)。我想返回所有 ID列表中的项目,但我也想知道哪些项目未被“收藏”。

我可以在一个查询中执行此操作,还是运行两个单独查询的最佳选择?

3 个答案:

答案 0 :(得分:1)

试试这个::

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

答案 1 :(得分:1)

我认为你需要在这里使用CROSS JOIN,因为你想向所有用户显示所有项目,例如

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

答案 2 :(得分:0)

以下是我最终采取的方法:

(
    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

有这个问题吗?到目前为止,它似乎像我希望的那样......