我有一个简单的数据表,我想从查询中选择大约 40% 的行。
我现在可以通过首先查询找到行数然后运行另一个查询来排序并选择第 n 行来做到这一点:
select count(*) as `total` from mydata;
可能会返回类似 93, 93*0.4 = 37
select * from mydata order by `field` asc limit 37,1;
我可以将这两个查询组合成一个查询吗?
我有一个简单的数据表,我想从查询中选择大约 40% 的行。
我现在可以通过首先查询找到行数然后运行另一个查询来排序并选择第 n 行来做到这一点:
select count(*) as `total` from mydata;
可能会返回类似 93, 93*0.4 = 37
select * from mydata order by `field` asc limit 37,1;
我可以将这两个查询组合成一个查询吗?
这将为您提供大约第 40 个百分位,它返回 40% 的行小于它的行。它按行与第 40 个百分位的距离对行进行排序,因为没有行可能正好落在第 40 个百分位上。
SELECT m1.field, m1.otherfield, count(m2.field)
FROM mydata m1 INNER JOIN mydata m2 ON m2.field<m1.field
GROUP BY
m1.field,m1.otherfield
ORDER BY
ABS(0.4-(count(m2.field)/(select count(*) from mydata)))
LIMIT 1
作为徒劳的练习(您当前的解决方案可能会更快且更受欢迎),如果表是 MYISAM(或者您可以使用 InnoDB 的近似值):
SET @row =0;
SELECT x.*
FROM information_schema.tables
JOIN (
SELECT @row := @row+1 as 'row',mydata.*
FROM mydata
ORDER BY field ASC
) x
ON x.row = round(information_schema.tables.table_rows * 0.4)
WHERE information_schema.tables.table_schema = database()
AND information_schema.tables.table_name = 'mydata';
还有这个解决方案,它使用了 GROUP_CONCAT 制作的怪物字符串。我必须像这样提高输出的最大值才能让它工作:
SET SESSION group_concat_max_len = 1000000;
那里的 MySql 向导:随意评论这些方法的相对性能。