首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mysql -在列中选择每个用户最近的活动

mysql -在列中选择每个用户最近的活动
EN

Stack Overflow用户
提问于 2016-10-11 08:51:07
回答 1查看 169关注 0票数 1

编辑-我发现它与https://stackoverflow.com/questions/12004603/mysql-pivot-row-into-dynamic-number-of-columns不同。因为在我的例子中,它是基于日期的

我的桌子上有链接的数据。我希望将每个客户最近的活动返回到列中,就像用于数据挖掘的时态数据一样。

所以我的桌子上有这样的栏:

代码语言:javascript
复制
id_user | item_id | date

      1 |       2 | 2016-11-10
      1 |       3 | 2016-9-9
      1 |      23 | 2016-8-8
      1 |      21 | 2016-6-6
      1 |       5 | 2016-7-7
      1 |       4 | 2016-10-10
      2 |       3 | 2016-9-9
      2 |       4 | 2016-10-10
      2 |      21 | 2016-5-4
      3 |       4 | 2016-10-10
      3 |       4 | 2016-9-9

First -我想过滤数据以获得“ 5”活动。然后我想出了这个代码

代码语言:javascript
复制
set @num := 0, @group := '';

select x.`id_user`, x.`item_id`, x.`date`
from
(
   select `id_user`, `item_id`, `date`,
      @num := if(@group = `id_user`, @num + 1, 1) as row_number,
      @group := `id_user` as dummy
  from ratings
  order by `id_user`, `date` desc, `item_id`
) as x,
where x.row_number <= 5
ORDER BY x.`user_id`, x.date DESC;

这些代码给了我这个表:

代码语言:javascript
复制
 id_user | item_id | date

       1 |       2 | 2016-11-10
       1 |       4 | 2016-10-10
       1 |       3 | 2016-9-9
       1 |      23 | 2016-8-8
       1 |       5 | 2016-7-7
       2 |       4 | 2016-10-10
       2 |       3 | 2016-9-9
       2 |      21 | 2016-5-4
       3 |       4 | 2016-10-10
       3 |       4 | 2016-9-9

但是-我想要这样的东西来进行数据挖掘

代码语言:javascript
复制
Id_user | item_1 | Item_2 | Item_3 | Item_4 | Item_5

      1 |      2 |      4 |      3 |     23 |      5 |
      2 |      4 |      3 |     21 |   NULL |   NULL |
      3 |      4 |      4 |   NULL |   NULL |   NULL |

你知道我的主意了吗?对不起,如果我不能解释清楚,希望你能理解我想要什么。

问题

  1. 如何对这些问题进行SQL查询?(目前我从MySQL数据库获得原始数据)
  2. 对这一问题是否有更好的解决办法?我希望这是个最佳做法。
EN

回答 1

Stack Overflow用户

发布于 2016-10-11 11:09:50

首先,在使用变量时,不要在不同的表达式中分配和使用变量。MySQL不保证SELECT中表达式的计算顺序。事实上,在某些情况下,以不同的顺序对它们进行评估。

因此,这应该是您的查询:

代码语言:javascript
复制
select r.`id_user`, r.`item_id`, r.`date`
from (select `id_user`, `item_id`, `date`,
             (@num := if(@u = id_user, @num + 1,
                         if(@u := id_user, 1, 1)
                        )
              ) as num
      from ratings r cross join
           (select @num := 0, @u := -1) params
      order by `id_user`, `date` desc, `item_id`
     ) r
where x.row_number <= 5
order by x.`user_id`, x.date desc;

然后,只需使用条件聚合:

代码语言:javascript
复制
select r.`id_user`,
       max(case when num = 1 then r.item_id end) as item_id_1,
       max(case when num = 2 then r.item_id end) as item_id_2,
       max(case when num = 3 then r.item_id end) as item_id_3,
       max(case when num = 4 then r.item_id end) as item_id_4,
       max(case when num = 5 then r.item_id end) as item_id_5
from (select `id_user`, `item_id`, `date`,
             (@num := if(@u = id_user, @num + 1,
                         if(@u := id_user, 1, 1)
                        )
              ) as num
      from ratings r cross join
           (select @num := 0, @u := -1) params
      order by `id_user`, `date` desc, `item_id`
     ) r
where x.row_number <= 5
group by x.`user_id`;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39973581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档