Mysql - 从分组数据中获取n个结果

时间:2016-03-30 01:50:30

标签: mysql

我试图通过记录获得每组随机N个结果,并且查询无效,

  SELECT `img_url`
   FROM
     (SELECT img_url, 
                  @image_rank := IF(@current_category = category_child, @country_rank + 1, 1) AS image_rank,
                  @current_category := category_child 
       FROM images
       ORDER BY category_child, rand()
     ) ranked
   WHERE image_rank <= 5

当我运行子查询时,image_rank始终为1,每个类别和30个类别我有超过1000个图像。

2 个答案:

答案 0 :(得分:1)

在您的帖子中@country_rank应为@image_rank。此外,user variables中还添加了使用过的CROSS JOIN的初始化。

要获得兰特N选择,ORDER BY rand()应该在image_rank代之前。

SELECT category_child, `img_url`, image_rank
FROM
 (SELECT img_url, 
           @image_rank := IF(@current_category = category_child, @image_rank + 1, 1) AS image_rank,
           @current_category := category_child AS category_child
   FROM (SELECT * FROM images ORDER BY category_child, rand()) AS images_rand CROSS JOIN 
      (SELECT @image_rank := 0, @current_category := NULL) param
 ) ranked
WHERE image_rank <= 5;

这是一个演示:

SQL:

-- data
create table images( category_child int, img_url char(20));
insert into images values
(1,'d'),(1,'c'),(1,'a'),(1,'b'),(1,'x'),(1,'s'),
(2,'d'),(2,'c'),(2,'a'),(2,'b'),(2,'x'),(2,'s');
select * from images;

-- Query wanted
SELECT category_child, `img_url`, image_rank
FROM
 (SELECT img_url, 
           @image_rank := IF(@current_category = category_child, @image_rank + 1, 1) AS image_rank,
           @current_category := category_child AS category_child
   FROM (SELECT * FROM images ORDER BY category_child, rand()) AS images_rand CROSS JOIN 
      (SELECT @image_rank := 0, @current_category := NULL) param
 ) ranked
WHERE image_rank <= 5;

输出:

mysql> select * from images;
+----------------+---------+
| category_child | img_url |
+----------------+---------+
|              1 | d       |
|              1 | c       |
|              1 | a       |
|              1 | b       |
|              1 | x       |
|              1 | s       |
|              2 | d       |
|              2 | c       |
|              2 | a       |
|              2 | b       |
|              2 | x       |
|              2 | s       |
+----------------+---------+
12 rows in set (0.00 sec)

mysql> -- Query wanted
mysql> SELECT category_child, `img_url`, image_rank
    -> FROM
    ->  (SELECT img_url,
    ->            @image_rank := IF(@current_category = category_child, @image_rank + 1, 1) AS image_rank,
    ->            @current_category := category_child AS category_child
    ->    FROM (SELECT * FROM images ORDER BY category_child, rand()) AS images_rand CROSS JOIN
    ->       (SELECT @image_rank := 0, @current_category := NULL) param
    ->  ) ranked
    -> WHERE image_rank <= 5;
+----------------+---------+------------+
| category_child | img_url | image_rank |
+----------------+---------+------------+
|              1 | s       |          1 |
|              1 | x       |          2 |
|              1 | b       |          3 |
|              1 | c       |          4 |
|              1 | d       |          5 |
|              2 | b       |          1 |
|              2 | s       |          2 |
|              2 | x       |          3 |
|              2 | c       |          4 |
|              2 | a       |          5 |
+----------------+---------+------------+
10 rows in set (0.00 sec)

-- Run again and generate different rand selection
mysql> SELECT category_child, `img_url`, image_rank
    -> FROM
    ->  (SELECT img_url,
    ->            @image_rank := IF(@current_category = category_child, @image_rank + 1, 1) AS image_rank,
    ->            @current_category := category_child AS category_child
    ->    FROM (SELECT * FROM images ORDER BY category_child, rand()) AS images_rand CROSS JOIN
    ->       (SELECT @image_rank := 0, @current_category := NULL) param
    ->  ) ranked
    -> WHERE image_rank <= 5;
+----------------+---------+------------+
| category_child | img_url | image_rank |
+----------------+---------+------------+
|              1 | x       |          1 |
|              1 | c       |          2 |
|              1 | d       |          3 |
|              1 | a       |          4 |
|              1 | s       |          5 |
|              2 | a       |          1 |
|              2 | c       |          2 |
|              2 | s       |          3 |
|              2 | d       |          4 |
|              2 | x       |          5 |
+----------------+---------+------------+
10 rows in set (0.00 sec)

答案 1 :(得分:0)

在MySQL中使用变量时,不应将它们设置在一个表达式中并在另一个表达式中使用它们。 MySQL不保证select中表达式的评估顺序。因此,您需要将变量操作放在单个表达式中。此外,您应该初始化变量:

SELECT `img_url`
FROM (SELECT img_url, 
             (@image_rank := IF(@current_category = category_child, @image_rank + 1,
                                IF(@current_category := category_child, 1, 1)
                               )
             ) AS image_rank                  
     FROM images i CROSS JOIN
          (SELECT @current_category := '', @image_rank := 0) params
     ORDER BY category_child, rand()
    ) ranked
WHERE image_rank <= 5;