Со следующей таблицей MySQL:
+-----------------------------+
+ id INT UNSIGNED +
+ name VARCHAR(100) +
+-----------------------------+
Как выбрать одну строку И ее положение среди других строк в таблице при сортировке по name ASC
. Итак, если данные таблицы выглядят так при сортировке по имени:
+-----------------------------+
+ id | name +
+-----------------------------+
+ 5 | Alpha +
+ 7 | Beta +
+ 3 | Delta +
+ ..... +
+ 1 | Zed +
+-----------------------------+
Как я мог выбрать Beta
строку, получив текущую позицию этой строки? Набор результатов, который я ищу, будет примерно таким:
+-----------------------------+
+ id | position | name +
+-----------------------------+
+ 7 | 2 | Beta +
+-----------------------------+
Я могу сделать простое SELECT * FROM tbl ORDER BY name ASC
перечисление строк в PHP, но кажется расточительным загружать потенциально большой набор результатов только для одной строки.
sql
mysql
analytic-functions
leepowers
источник
источник
Ответы:
Использовать это:
SELECT x.id, x.position, x.name FROM (SELECT t.id, t.name, @rownum := @rownum + 1 AS position FROM TABLE t JOIN (SELECT @rownum := 0) r ORDER BY t.name) x WHERE x.name = 'Beta'
... чтобы получить уникальное значение позиции. Этот:
SELECT t.id, (SELECT COUNT(*) FROM TABLE x WHERE x.name <= t.name) AS position, t.name FROM TABLE t WHERE t.name = 'Beta'
... даст галстукам ту же ценность. IE: Если есть два значения на втором месте, они оба будут иметь позицию 2, когда первый запрос даст позицию 2 для одного из них и 3 для другого ...
источник
position
, но это прекрасно.Это единственный способ, о котором я могу думать:
SELECT `id`, (SELECT COUNT(*) FROM `table` WHERE `name` <= 'Beta') AS `position`, `name` FROM `table` WHERE `name` = 'Beta'
источник
name <= 'Beta'
вместо этогоposition
значения для галстуков.LIMIT 1
туда? В случае ничьей вы получите только один ряд с последней позицией галстука.name
поле уникально, то нет причин усложнять запрос. Если не может - то подождем его ожидания результата на ничейные имена.Если запрос простой и размер возвращаемого набора результатов потенциально велик, вы можете попытаться разделить его на два запроса.
Первый запрос с ограниченными критериями фильтрации только для извлечения данных из этой строки, а второй запрос использует предложение
COUNT
withWHERE
для вычисления позиции.Например в вашем случае
Запрос 1:
SELECT * FROM tbl WHERE name = 'Beta'
Запрос 2:
SELECT COUNT(1) FROM tbl WHERE name >= 'Beta'
Мы используем этот подход в таблице с 2M записями, и он намного более масштабируемый, чем подход OMG Ponies.
источник
Остальные ответы кажутся мне слишком сложными.
Вот простой пример , допустим, у вас есть таблица со столбцами:
и вы хотите отсортировать идентификаторы пользователей по точкам и получить позицию в строке («рейтинг» пользователя), тогда вы используете:
SET @row_number = 0; SELECT (@row_number:=@row_number + 1) AS num, userid, points FROM ourtable ORDER BY points DESC
num
дает вам позицию в строке (рейтинг).Если у вас MySQL 8.0+, вы можете использовать ROW_NUMBER ()
источник
Положение строки в таблице показывает, сколько строк «лучше» целевой строки.
Итак, вы должны посчитать эти строки.
ВЫБЕРИТЕ СЧЕТЧИК (*) + 1 ОТ
table
ГДЕname
<'Бета'В случае ничьей возвращается самая высокая позиция.
Если вы добавите еще одну строку с тем же именем «Бета» после существующей строки «Бета», то возвращенная позиция будет по-прежнему 2, поскольку они будут занимать одно и то же место в классификации.
Надеюсь, это поможет людям, которые будут искать что-то подобное в будущем, поскольку я считаю, что владелец вопроса уже решил свою проблему.
источник
У меня очень похожая проблема, поэтому я не буду задавать тот же вопрос, но я расскажу здесь, что я сделал, мне пришлось использовать также группу по и заказ по AVG. Есть студенты с подписями и сокором, и мне пришлось их ранжировать (другими словами, я сначала вычисляю AVG, затем упорядочиваю их в DESC, а затем, наконец, мне нужно было добавить позицию (рейтинг для меня), поэтому я сделал что-то очень похожее на лучший ответ здесь, с небольшими изменениями, которые соответствуют моей проблеме):
Наконец, я помещаю
position
столбец (рейтинг для меня) во внешний SELECTSET @rank=0; SELECT @rank := @rank + 1 AS ranking, t.avg, t.name FROM(SELECT avg(students_signatures.score) as avg, students.name as name FROM alumnos_materia JOIN (SELECT @rownum := 0) r left JOIN students ON students.id=students_signatures.id_student GROUP BY students.name order by avg DESC) t
источник
Я просматривал принятый ответ, и он казался немного сложным, поэтому вот его упрощенная версия.
SELECT t,COUNT(*) AS position FROM t WHERE name <= 'search string' ORDER BY name
источник
У меня есть проблемы аналогичного типа, когда мне требуется ранг ( индекс ) таблицы
order by votes desc
. Следующее отлично работает для меня.Select *, ROW_NUMBER() OVER(ORDER BY votes DESC) as "rank" From "category_model" where ("model_type" = ? and "category_id" = ?)
источник
может быть то, что вам нужно, это добавить синтаксис
так что используйте
SELECT * FROM tbl ORDER BY name ASC LIMIT 1
если вам нужна всего одна строка ..
источник