从MySQL查询的顶部和底部切断13%?

时间:2009-02-04 16:31:06

标签: mysql

我目前正在尝试优化一些查询和脚本,我想知道是否有办法切断MySQL结果集的某个百分比?

例如,我有一个像这样的查询:

SELECT TrackingID, OpenTime, FirstPoint
FROM PointsTable

我需要“中间”74%,由FirstPointGMT和OpenTimeGMT之间的差异排序,这意味着:我需要切断顶部和底部的13%。

目前,脚本将获取所有行,按持续时间计算和排序,然后将其删除,但我希望在SQL查询中执行此操作,以使脚本更清晰。

我知道LIMIT条款,但这似乎不支持像“13%”这样的相对值。

任何人都可以判断a)是否实际上只有SQL可以实现; b)如何实现?

MySQL是5.0.45。

PS:是的,我知道13%似乎是一个非常奇怪的数字,但这都是一个更大的过程的一部分。

4 个答案:

答案 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%。