SQL查询,每个用户只检索两行

时间:2012-03-09 16:31:47

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

我有这个包含广告ID和用户ID的表格。 任何一个用户都可能拥有多个广告。 我想每个用户只展示两个广告(如果他只有一个广告则展示一个广告)。输出必须是随机的。

CREATE TABLE IF NOT EXISTS `ads` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_user` int(12) NOT NULL,
  `title` varchar(255) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

表格包含:

1, 1, 'erfw', 'google.pt'
2, 2, 'yhtg', 'google.pt'
3, 2, 'gfddfg', 'google.pt'
4, 3, 'ehgfd', 'google.pt'
5, 2, '435yet', 'google.pt'
6, 1, 'ikkt', 'google.pt'
7, 1, 'wyrths', 'google.pt'

输出应为:

1, 1, 'erfw', 'google.pt'
2, 2, 'yhtg', 'google.pt'
3, 2, 'gfddfg', 'google.pt'
4, 3, 'ehgfd', 'google.pt'
6, 1, 'ikkt', 'google.pt'

输出必须不时不同,以随机获取所有广告。

2 个答案:

答案 0 :(得分:0)

这看起来像这个问题的一个非常相似的问题:

How to do equivalent of "limit distinct"?

SELECTLIMIT使用两个嵌套DISTINCT查询应该可以帮到你。

答案 1 :(得分:0)

在MySQL中,执行任何Greatest-n-per-group将使用MySQL变量保留最后一个“东西”,另一个用于“编号”赋值(在这种情况下你想要随机)

select
      PreQuery.*,
   from
      ( select @lastUser := 0,
               @lastAdSeq := 0 ) sqlvars,
      ( select
              ads.id_user,
              ads.id,
              ads.title,
              ads.url,
              @lastAdSeq := if( @lastUser = ads.id, @lastAdSeq +1, 1 ) as Seq,
              @lastUser := ads.id_user as carryover
           from
              ads
           order by
              ads.id_user,
              rand() 
           having Seq <= 2 ) PreQuery

“HAVING”子句对于理解this clarifies that“HAVING”子句在任何“GROUP BY”或“ORDER BY”之后应用并且应用于结果集中的记录之后是至关重要的。 (并没有使用任何WHERE子句进行优化)。

也就是说,我们通过广告查询,按用户的ID排序,但随机排在第二位。这迫使所有人的“广告”随机化。之后,应用@变量并构建每个用户的序列计数。然后应用having子句,一旦达到3或更多,结果将被抛出最终结果集。而且每个用户只剩下最多2个广告。

需要先做,以确保查询订购的数据