Обрезать 13% сверху и снизу MySQL Query? - PullRequest
3 голосов
/ 04 февраля 2009

В настоящее время я пытаюсь оптимизировать несколько запросов и сценариев, и мне интересно, есть ли способ обрезать определенный процент от MySQL Result Set?

например, у меня есть такой запрос:

SELECT TrackingID, OpenTime, FirstPoint
FROM PointsTable

Мне нужны «средние» 74%, упорядоченные по разнице между FirstPointGMT и OpenTimeGMT, что означает: мне нужно отрезать верхнюю и нижнюю 13%.

На данный момент сценарий просто получает все строки, вычисляет и упорядочивает по длительности, а затем обрезает их, но я бы хотел сделать это в SQL-запросе, если это возможно, чтобы сделать сценарий более понятным.

Я знаю о предложении LIMIT, но, похоже, это не поддерживает относительные значения, такие как "13 процентов".

Может ли кто-нибудь сказать, а) если это возможно на самом деле только с помощью SQL и б) как этого можно достичь?

MySQL - 5.0.45.

PS: И да, я знаю, что 13% кажется очень странным числом, но это все часть более крупного процесса.

Ответы [ 4 ]

4 голосов
/ 04 февраля 2009

Вам нужно ОГРАНИЧИТЬ данные, которые вы возвращаете, на какой процентиль находятся возвращаемые строки в наборе результатов.

Попробуйте это:

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/100-й (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) 
)

РЕДАКТИРОВАТЬ: После просмотра ответа Нияза, я понял, что запрос может быть переписан как:

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% всех строк вне таблицы с этой точки.

2 голосов
/ 04 февраля 2009

Для этого вам придется использовать два запроса.

Во-первых:

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 на его значение.

Я не знаю, как это сделать одним запросом.

1 голос
/ 04 февраля 2009

Вырезание определенного процента будет означать, что запрос по-прежнему должен оцениваться полностью, поскольку для вычисления процента должно быть известно количество результатов.

Однако вы можете сэкономить пропускную способность / процессор, не получая нежелательные результаты из базы данных, но это зависит от вашего драйвера базы данных.

0 голосов
/ 04 февраля 2009

Вы не сможете сделать это за один запрос. Это заняло бы как минимум 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%.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...