我目前正在尝试优化一些查询和脚本,我想知道是否有办法切断MySQL结果集的某个百分比?
例如,我有一个像这样的查询:
SELECT TrackingID, OpenTime, FirstPoint
FROM PointsTable
我需要“中间”74%,由FirstPointGMT和OpenTimeGMT之间的差异排序,这意味着:我需要切断顶部和底部的13%。
目前,脚本将获取所有行,按持续时间计算和排序,然后将其删除,但我希望在SQL查询中执行此操作,以使脚本更清晰。
我知道LIMIT条款,但这似乎不支持像“13%”这样的相对值。
任何人都可以判断a)是否实际上只有SQL可以实现; b)如何实现?
MySQL是5.0.45。
PS:是的,我知道13%似乎是一个非常奇怪的数字,但这都是一个更大的过程的一部分。
答案 0 :(得分:4)
您需要将返回的数据限制为结果集中返回的行的百分位数。
试试这个:
SELECT TrackingID, OpenTime, FirstPoint
FROM PointsTable
ORDER BY FirstPointGMT - OpenTimeGMT
LIMIT (13*((SELECT COUNT(*) FROM PointsTable) +1) / 100),
((SELECT COUNT(*) FROM PointsTable)
-
(26*((SELECT COUNT(*) FROM PointsTable) +1) / 100)
)
上述
的说明这里唯一棘手的问题是Limit子句及其语法:
> LIMIT start_row,number_of_rows_to_return
我们的start_row需要是结果集中第一个记录13 / 100th(13%)之后的第一个元素。为此,我们使用以下公式:
rownumber_or_number_of_rows_in_resultset_Npercent_in =
( Npercent * ( number_of_rows_in_resultset + 1) / 100)
是(13*((SELECT COUNT(*) FROM PointsTable) +1) / 100)
。
我们的number_of_rows_to_return必须是行总数,减去行数的26%(从底部开始占13%,从顶部开始占13%),或者
(total_number_of_rows - number_of_rows_26percent_of_the_way_in)
因此实际计算如下:
( (SELECT COUNT(*) FROM PointsTable)
-
(26*((SELECT COUNT(*) FROM PointsTable) +1) / 100)
)
编辑:在查看了Niyaz的回复后,我意识到查询可以改写为:
SELECT TrackingID, OpenTime, FirstPoint
FROM PointsTable
ORDER BY FirstPointGMT - OpenTimeGMT
LIMIT (13*((SELECT COUNT(*) FROM PointsTable) +1) / 100),
(74*((SELECT COUNT(*) FROM PointsTable) +1) / 100)
这更干净,因为它消除了第三个嵌套查询,并且应该在功能上等效。限制行,从顶部开始的行数为13%,并从该点开始显示表格中总行数的74%。
答案 1 :(得分:2)
您必须使用两个查询。
首先:
SELECT count(*) as c
FROM PointsTable;
然后在php中找到以下内容:
a = c * 13 / 100
b = c * 74 / 100
第二
SELECT TrackingID, OpenTime, FirstPoint
FROM PointsTable
LIMIT a,b;
请记住用其值替换a,b。
我不知道在单个查询中执行此操作的方法。
答案 2 :(得分:1)
切断某个百分比意味着仍然必须完整地评估查询,因为必须知道结果的数量才能计算百分比。
但是,您可以通过不从数据库中检索不需要的结果来节省一些带宽/ CPU,但这取决于您的数据库驱动程序。
答案 3 :(得分:0)
您将无法在单个查询中执行此操作。沿着这些方向至少需要3个:
select sql_calc_found_rows fields from table where conditions limit 0; select @cnt := found_rows(); select fields from table where conditions limit @cnt*0.13,@cnt-@cnt*0.13
额外的'sql calc found rows参数'导致MySQL确定如果limit子句不愉快将检索多少行,然后使用found_rows()函数检索,并使用它来重新运行查询有适当的数字限制可以得到74%。