【问题标题】:MySQL - a subquery and a WHERE INMySQL - 一个子查询和一个 WHERE IN
【发布时间】:2013-02-01 13:01:51
【问题描述】:

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

  • 身份证
  • item_id
  • user_id
  • 最喜欢的(布尔)

当用户“收藏”一个项目时,它会使用项目 ID、用户 ID 在此表中添加一行,并将收藏属性设置为 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 列表中的项目,但我也想知道哪些项目没有被“收藏”。

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

【问题讨论】:

    标签: mysql sql


    【解决方案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
    

    【讨论】:

    • 感谢 Sashi 的回复,但 John Woo 是正确的:我需要不喜欢的项目也出现在结果中。
    【解决方案2】:

    我认为您需要在这里使用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
    

    【讨论】:

    • 太棒了 - 非常感谢!我将不得不对此进行研究以弄清楚发生了什么,但它运行良好。
    • 这似乎在我使用自己的用户 ID 进行测试期间有效,但在我使用另一个用户 ID 时却没有。我终于意识到它只有在用户“收藏”至少一个项目时才有效(所以他们在 user_favorites 表中有一行)。换句话说,如果用户没有收藏项目,则返回零结果。关于如何解决这个问题的任何建议?
    【解决方案3】:

    这是我最终采用的方法:

    (
        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
    

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

    【讨论】:

      猜你喜欢
      • 2015-09-17
      • 1970-01-01
      • 2012-08-04
      • 1970-01-01
      • 2012-07-02
      • 2021-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多