【问题标题】:Join top 3 interest fields along with each user row加入前 3 个兴趣字段以及每个用户行
【发布时间】:2013-03-02 03:20:12
【问题描述】:

我正在尝试获取每个用户的前 3 个兴趣,可能作为 LEFT JOIN 查询。

应用程序的设计方式是,每个用户都有一组兴趣,这些兴趣不外乎categories 表的“孩子”(没有parent 的行)。

以下是一些带有模拟数据的简化表架构(请参阅 SQL Fiddle demo

-- Users table

| ID |  NAME |
--------------
|  1 |  John |
|  2 |  Mary |
|  3 | Chris |


-- Categories table                           -- Interests table

| ID |                 NAME | PARENT |        | ID | USER_ID | CATEGORY_ID |
--------------------------------------        ------------------------------
|  1 |      Web Development | (null) |        |  1 |       1 |           1 |
|  2 |          Mobile Apps | (null) |        |  2 |       1 |           1 |
|  3 | Software Development | (null) |        |  3 |       1 |           1 |
|  4 |    Marketing & Sales | (null) |        |  4 |       2 |           1 |
|  5 |             Web Apps |      1 |        |  5 |       2 |           1 |
|  6 |                  CSS |      1 |        |  6 |       3 |           1 |
|  7 |                  iOS |      2 |        |  7 |       3 |           1 |
|  8 |      Streaming Media |      3 |        |  8 |       3 |           1 |
|  9 |                  SEO |      4 |        
| 10 |                  SEM |      4 |        

为了获得给定用户的前 3 个兴趣,我通常执行以下查询:

SELECT `c`.`parent` as `category_id` 
FROM `interests` `i` LEFT JOIN `categories` `c` ON `c`.`id` = `i`.`category_id` 
WHERE `i`.`user_id` = '2' 
GROUP BY `c`.`parent` 
ORDER BY count(`c`.`parent`) DESC LIMIT 3

此查询返回 id = 2 的用户的前 3 个categories(父母)

我想了解如何查询 users 表并在 3 个不同字段(首选)中或在一个字段中以 group_concat(..) 的形式获取他们的前 3 个类别

SELECT id, name, top_categories FROM users, (...) WHERE id IN ('1', '2', '3');

任何想法我应该如何去做? 谢谢!

【问题讨论】:

  • 那么,您希望每个用户 (1,2,3) 有一行吗?每一行都会显示他们的前 3 个类别?
  • 没错,比如:'1', 'John', 'cat_id1,cat_id2,cat_id3''1', 'John', 'cat_id1' , 'cat_id2' , 'cat_id3'
  • 如果一个用户只有 2 个兴趣是 null 你想看到的第 3 个,如果一个用户有 4 个兴趣,什么规则控制你想要的 3 个?选择“前 3 个”?最后,上面的示例数据显示用户 1、2 和 3 在所有情况下都对 Web 开发有相同的兴趣。您希望 Web 开发被列出 3 次还是您想要不同的兴趣?
  • @xQbert 如果用户只有 2 个兴趣,我不介意它是忽略它还是在第 3 个返回 NULL。然而,结果必须是前 3 个类别字段。例如如果用户对“营销和销售”最感兴趣,那么 top_categories 的第一个预期结果应该是 4,然后是他们最感兴趣的任何其他“父类别”

标签: mysql sql greatest-n-per-group group-concat


【解决方案1】:

在 MYSQL 中获取每个用户的前 3 条记录是一种非常粗略的方法

 SELECT u.id, c.name 
 FROM 
     users u, 
     categories c, 
     (SELECT i.id, 
         i.user_id, 
         i.category_id, 
         @running:=if(@previous=i.user_id,@running,0) + 1 as rId,
         @previous:=i.user_id
     FROM 
         (SELECT * FROM intersect ORDER BY user_id) i JOIN 
         (SELECT @running=0, @previous=0 ) r) i
 WHERE 
     u.id = i.USER_ID AND
     i.CATEGORY_ID = c.id AND 
     i.rId <= 3
 group by u.id, c.name ;

希望对你有帮助

FIDDLE

【讨论】:

    【解决方案2】:

    首先构建一个在不同行上列出每个用户的前三项技能的摸索式查询。然后将其转入以将每个用户的三个技能拉到右侧。您需要对每个技能列中的技能使用 Max(isnull(skill,'')) 表达式。

    【讨论】:

    • Pieter,你能用一些代码展示你是如何做到这一点的吗?谢谢!
    • 我用的是sql-server,不是mySql,所以我对MySql的语法知识不足;我也将在一分钟内下线。明天试试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2022-01-13
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    相关资源
    最近更新 更多