Mysql MariaDB 10.3.18:如何获得2条随机且不同值的记录?
有一个名为stat的MySQL表:Mysql MariaDB 10.3.18:如何获得2条随机且不同值的记录?,mysql,sql,mariadb,groupwise-maximum,Mysql,Sql,Mariadb,Groupwise Maximum,有一个名为stat的MySQL表: line_name device_name count 1001 3548001 2 1002 3548002 3 1003 3548003 6 2001 3548004 7 2002 3548005 3 2003 3548006 4 3001 3548007 3 3002 3548008 9 3003 3548009 7 我需要选择两条记录,其中第_行名称中的第一个字符不同 例如:
line_name device_name count
1001 3548001 2
1002 3548002 3
1003 3548003 6
2001 3548004 7
2002 3548005 3
2003 3548006 4
3001 3548007 3
3002 3548008 9
3003 3548009 7
我需要选择两条记录,其中第_行名称中的第一个字符不同
例如:
1001 3548001 2
3003 3548009 7
或:
我试过这个:
SELECT DISTINCT(SUBSTRING(line_name,1,LENGTH(line_name)-3)) as pack_id, device_name, count
from stat
order by rand()
limit 2;
但有时我会在结果集中得到相同的pack\u id您可以按pack\u id分组,并随机选择相应的设备名称或任何值(如果您使用的是MySQL>=5.7)
SELECT
SUBSTR(line_name, 1, 1) AS pack_id,
line_name,
ANY_VALUE(device_name) AS device_name,
count
FROM stat
GROUP BY pack_id
ORDER BY RAND()
LIMIT 2
较旧的MySQL版本
SELECT
SUBSTR(line_name, 1, 1) AS pack_id,
line_name,
device_name,
count
FROM stat
GROUP BY pack_id
ORDER BY RAND()
LIMIT 2
请注意,我还简化了MySQL 8.0中pack_id的计算,您可以在CTE中自联接表,以查找满足条件的随机记录对,然后使用UNION ALL取消对结果的绑定:
WITH cte AS (
SELECT
t1.line_name line_name1,
t1.device_name device_name1,
t1.count count1,
t2.line_name line_name2,
t2.device_name device_name2,
t2.count count2
FROM stat t1
INNER JOIN stat t2 ON LEFT(t1.line_name, 1) != LEFT(t2.line_name, 1)
ORDER BY RAND()
LIMIT 1
)
SELECT line_name1, device_name1, count1 FROM cte
UNION ALL
SELECT line_name2, device_name2, count2 FROM cte
:
运行1:
| line_name1 | device_name1 | count1 |
| ---------- | ------------ | ------ |
| 3001 | 3548007 | 3 |
| 2001 | 3548004 | 7 |
运行2:
| line_name1 | device_name1 | count1 |
| ---------- | ------------ | ------ |
| 1003 | 3548003 | 6 |
| 2002 | 3548005 | 3 |
在MariaDB 10.3中,您可以使用ROW_NUMBER OVER ORDER BY RAND为每个不同的行名称生成一个随机行号,然后选择一对ROW NUMBER=1的随机值:
WITH cte AS
(SELECT *, ROW_NUMBER() OVER (PARTITION BY LEFT(line_name, 1) ORDER BY RAND()) AS rn
FROM stat)
SELECT `line_name`, `device_name`, `count`
FROM cte
WHERE rn = 1
ORDER BY RAND()
LIMIT 2
几次运行的输出
line_name device_name count
1003 3548003 6
3002 3548008 9
line_name device_name count
2001 3548004 7
1003 3548003 6
我只想:
select s.*
from stat s
order by row_number() over (partition by left(line_name, 1)
order by rand()
)
limit 2;
不需要子查询,因为按顺序允许使用窗口函数
这可能不是最有效的方法。但是,除非您的表很大,否则性能应该可以。此外,很明显,此查询无法返回该结果!草莓,是的,你说得对。我编辑的questionDistinct不是一个函数,它适用于整行。请提供SHOW CREATE TABLE。我想知道的一件事是线路名称是否是“唯一的”。虽然这是一个很好的方法,但这个答案将设备名称限制为每线路名称的最大值。然而,OP需要所有数据都是随机的。我不认为尾部限制2是必要的。@RickJames鉴于LEFTline_名称,1可以基于相同的数据1、2或3取值,CTE中将有3行rn=1。看到可爱的,但不要期待性能。对于仅仅9行的表,38个处理程序读取34个处理程序读取下一个21个处理程序tmp写入9个处理程序更新10个Innodb缓冲池读取请求9个Innodb行读取
select s.*
from stat s
order by row_number() over (partition by left(line_name, 1)
order by rand()
)
limit 2;