2009-12-16 5 views
1

У меня есть таблица с 50 столбцами и 1000 строк. Я хочу вывести первые 5 записей для каждого столбца. Для того, чтобы получить 1 запись я делаю:Как получить верхние значения N каждого столбца в MySql

SELECT MAX(column1), MAX(column2), MAX(column3) FROM table 

Это получает верхнее значение для каждого столбца, но как я могу получить второе «максимальное» значение п раз?

ответ

3

Это НЕ то, что вы хотите сделать в одном запросе. Просто сломайте его, по одному запросу для каждого столбца. При правильных обстоятельствах (например, с правильными индексами и правильными типами столбцов) MySQL может фактически оптимизировать эти запросы путем короткого замыкания, так что ему никогда не придется сканировать всю таблицу, он просто извлекает верхние 5 значений и делает.

SELECT column1 FROM table ORDER BY column1 DESC LIMIT 5 
SELECT column2 FROM table ORDER BY column2 DESC LIMIT 5 
etc 

Если вы пытаетесь smoosh их всех вместе в один гигантский, запутано запрос вам только удастся убедить оптимизатор просто отказаться и отсканировать всю таблицу в 50 раз, а затем использовать 50 временных таблиц и, возможно, некоторые сортировка файлов для хорошей оценки. Поэтому, если в вашей таблице не содержится около 10 строк (что, очевидно, нет), 50 отдельных запросов всегда будут быстрее.

-1
SELECT MAX(column1), MAX(column2), MAX(column3) FROM table LIMIT n 

где п = число раз

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

0

Может быть, лучше, но вы можете просто вложить выражения SELECT.

Что-то вроде:

SELECT (SELECT column1 FROM table ORDER BY column1 LIMIT 5) a, 
     (SELECT column2 FROM table ORDER BY column2 LIMIT 5) b, 
     (SELECT column3 FROM table ORDER BY column3 LIMIT 5) c 

добавить "FROM DUAL", если вы используете Oracle.

+0

Это решение, но есть ли более короткий способ его записи, чтобы избежать 50+ вложенных запросов выбора, будет ли это большой нагрузкой для расчета? –

+0

-1 Подзапросы не могут возвращать более одной строки – Andomar

+0

@Andomar да, они могут. Я просто проверил это. однако вам нужно их псевдоним, который я пропустил в этом посте. теперь исправлено. – Verhogen

0

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

Объяснение: выражения в списке выбора SQL-запроса должны относятся к одной и той же строке. Таким образом, вы могли бы получить в первую пятерку значений column1 таким образом:

SELECT column1, column2, column3 FROM table ORDER BY column1 DESC LIMIT 5; 

Но, конечно, значения column2 и column3 не обязательно будет наибольшие значения в этих столбцах, они будут любые значения, случается в той же строке с наибольшими значениями в column1.

Единственный способ получить значения из разных строк таблицы в одном списке выбора является сделать автообъединение:

SET @i1 = 0, @i2 = 0, @i3 = 0, @i4 = 0, @i5 = 0; 
SELECT * 
FROM (SELECT @i1:[email protected]+1 AS i, column1 FROM table ORDER BY column1 DESC LIMIT 5) t1 ON (t1.i = t5.i) 
JOIN (SELECT @i2:[email protected]+1 AS i, column2 FROM table ORDER BY column2 DESC LIMIT 5) t2 ON (t1.i = t5.i) 
JOIN (SELECT @i3:[email protected]+1 AS i, column3 FROM table ORDER BY column3 DESC LIMIT 5) t3 ON (t1.i = t5.i) 
JOIN (SELECT @i4:[email protected]+1 AS i, column4 FROM table ORDER BY column4 DESC LIMIT 5) t4 ON (t1.i = t5.i) 
JOIN (SELECT @i5:[email protected]+1 AS i, column5 FROM table ORDER BY column5 DESC LIMIT 5) t5 ON (t1.i = t5.i); 

Но это не практично или эффективно 50 колонн ,

Мне также нужно задаться вопросом о вашем дизайне базы данных. Если вам нужна пятерка из 50 столбцов, может быть, все они хранят такую ​​же информацию? Вы можете практиковать Многоколоночные атрибуты antipattern. Если это так, вы должны поместить все 50 столбцов в один столбец в дочернюю таблицу.

+1

. если вы спуститесь вниз. –

Смежные вопросы