mysql查询从3个类别中获取随机项目

标签 mysql

我有一个 mysql 表,其中包含 3 种类型的数据(文本、图像、视频) $type 列保存数据的类型。 (类型 = 1 表示文本,2 表示图像,3 表示视频)

我的要求是需要从表中获取20条记录的随机数据,这样它应该有8个文本,8个图像和4个视频。

另外,前 2 个记录的结果应该是图像,接下来 1 个视频和接下来 2 个文本,然后再次重复。

最佳答案

这是一个 MariaDB 10.1 查询,可以满足您的需求。它首先随机选择8个文本、4个视频和8个图像。然后,它为每种类型的数据分配行号,并使用这些行号将值分组在一起(2 个文本、1 个视频、2 个图像)和 ELT功能在组内按图像、视频、文本顺序排序。

SELECT type, value
FROM (
SELECT value, @rn := IF(type = @type, @rn + 1, 1) AS row, @type := type AS type
FROM (
(SELECT type, value
 FROM data
 WHERE type = 1
 ORDER BY RAND()
 LIMIT 8)
UNION ALL
(SELECT type, value
 FROM data
 WHERE type = 2
 ORDER BY RAND()
 LIMIT 8)
UNION ALL
(SELECT type, value 
 FROM data
 WHERE type = 3
 ORDER BY RAND()
 LIMIT 4)
ORDER BY ELT(type, 3, 1, 2)
) d
CROSS JOIN (SELECT @rn := 0, @type := '') r) v
ORDER BY CASE WHEN type = 1 OR type = 2 THEN (row - 1) DIV 2
              ELSE row - 1 END,
         ELT(type, 3, 1, 2)

我做了一个demo on dbfiddle这表明它正在运行。

如果您升级到 MariaDB 10.2,您可以省去这些变量并使用 ROW_NUMBER :

WITH cte AS 
((SELECT type, value, ROW_NUMBER() OVER (PARTITION BY type ORDER BY RAND()) AS row
 FROM data
 WHERE type = 1
 LIMIT 8)
UNION ALL
(SELECT type, value, ROW_NUMBER() OVER (PARTITION BY type ORDER BY RAND()) AS row
 FROM data
 WHERE type = 2
 LIMIT 8)
UNION ALL
(SELECT type, value, ROW_NUMBER() OVER (PARTITION BY type ORDER BY RAND()) AS row 
 FROM data
 WHERE type = 3
 LIMIT 4)
)
SELECT type, value
FROM cte
ORDER BY CASE WHEN type = 1 OR type = 2 THEN (row - 1) DIV 2
              ELSE row - 1 END,
         ELT(type, 3, 1, 2)

此查询也在我的 demo 中进行了演示.

关于mysql查询从3个类别中获取随机项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58786155/

相关文章:

mysql - 排行榜位置SQL优化

php - 用户注册模块向PHP数据库插入空白数据

php - PDO 包装器返回 NULL

asp.net - 通用 SQL 参数在 ASP.NET 中的 MySQL 连接器的 SqlDataSource 中不起作用

mysql - Perl 函数 "waits"在返回 1 到 main 函数之前

php - 连接两个以上的 mysql 表,然后将行操作为分组的多维数组

mysql - 在php yii2中查询后打印特定数组值

mysql - 你怎么知道一个MySQL表是否被锁定?

php - 如何知道 Solr 搜索在 Magento CE 中的工作原理

mysql - 在 Gorm 中使用模型连接两个表的最佳方法是什么?