Con la siguiente tabla MySQL:
+-----------------------------+
+ id INT UNSIGNED             +
+ name VARCHAR(100)           +
+-----------------------------+
¿Cómo puedo seleccionar una sola fila Y su posición entre las otras filas de la tabla, cuando se ordena por name ASC. Entonces, si los datos de la tabla se ven así, cuando se ordenan por nombre:
+-----------------------------+
+ id | name                   +
+-----------------------------+
+  5 | Alpha                  +
+  7 | Beta                   +
+  3 | Delta                  +
+ .....                       +
+  1 | Zed                    +
+-----------------------------+
¿Cómo podría seleccionar la Betafila obteniendo la posición actual de esa fila? El conjunto de resultados que estoy buscando sería algo como esto:
+-----------------------------+
+ id | position | name        +
+-----------------------------+
+  7 |        2 | Beta        +
+-----------------------------+
Puedo hacer un simple y SELECT * FROM tbl ORDER BY name ASCluego enumerar las filas en PHP, pero parece un desperdicio cargar un conjunto de resultados potencialmente grande solo para una sola fila.  
                    
                        sql
                                mysql
                                analytic-functions
                                
                    
                    
                        leepowers
fuente
                
                fuente

Respuestas:
Utilizar esta:
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'... para obtener un valor de posición único. Esta:
SELECT t.id, (SELECT COUNT(*) FROM TABLE x WHERE x.name <= t.name) AS position, t.name FROM TABLE t WHERE t.name = 'Beta'... le dará a las corbatas el mismo valor. IE: Si hay dos valores en el segundo lugar, ambos tendrán una posición de 2 cuando la primera consulta dará una posición de 2 a uno de ellos y 3 a la otra ...
fuente
position, pero es perfecto.Esta es la única forma en la que puedo pensar:
SELECT `id`, (SELECT COUNT(*) FROM `table` WHERE `name` <= 'Beta') AS `position`, `name` FROM `table` WHERE `name` = 'Beta'fuente
name <= 'Beta'en su lugarpositionvalores para los empates.LIMIT 1allí? En caso de empate, obtendría solo una fila con la última posición del empate.namecampo sea único, entonces no hay razón para hacer la consulta más compleja. Si no puede, esperemos sus expectativas de resultados para nombres empatados.Si la consulta es simple y el tamaño del conjunto de resultados devuelto es potencialmente grande, entonces puede intentar dividirlo en dos consultas.
La primera consulta con un criterio de filtrado restringido solo para recuperar datos de esa fila, y la segunda consulta usa la cláusula
COUNTwithWHEREpara calcular la posición.Por ejemplo en tu caso
Consulta 1:
SELECT * FROM tbl WHERE name = 'Beta'Consulta 2:
SELECT COUNT(1) FROM tbl WHERE name >= 'Beta'Usamos este enfoque en una tabla con un registro de 2M y esto es mucho más escalable que el enfoque de OMG Ponies.
fuente
Las otras respuestas me parecen demasiado complicadas.
Aquí viene un ejemplo sencillo , digamos que tiene una tabla con columnas:
y desea ordenar los ID de usuario por puntos y obtener la posición de la fila (la "clasificación" del usuario), luego usa:
SET @row_number = 0; SELECT (@row_number:=@row_number + 1) AS num, userid, points FROM ourtable ORDER BY points DESCnumle da la posición de la fila (clasificación).Si tiene MySQL 8.0+, es posible que desee usar ROW_NUMBER ()
fuente
La posición de una fila en la tabla representa cuántas filas son "mejores" que la fila de destino.
Entonces, debes contar esas filas.
SELECCIONAR CONTADOR (*) + 1 DESDE
tableDONDEname<'Beta'En caso de empate, se devuelve la posición más alta.
Si agrega otra fila con el mismo nombre de "Beta" después de la fila "Beta" existente, la posición devuelta seguirá siendo 2, ya que compartirían el mismo lugar en la clasificación.
Espero que esto ayude a las personas que buscarán algo similar en el futuro, ya que creo que el propietario de la pregunta ya resolvió su problema.
fuente
Tengo un problema muy, muy similar, por eso no haré la misma pregunta, pero compartiré aquí qué hice, tuve que usar también un grupo por y un pedido por AVG. Hay estudiantes, con firmas y socore, y tuve que clasificarlos (en otras palabras, primero calculé el AVG, luego los ordené en DESC, y finalmente necesitaba agregar la posición (rango para mí), así que lo hice algo muy similar a la mejor respuesta aquí, con pequeños cambios que se ajustan a mi problema):
Puse finalmente la
positioncolumna (rango para mí) en el SELECT externoSET @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) tfuente
Estaba revisando la respuesta aceptada y parecía un poco complicado, así que aquí está la versión simplificada.
SELECT t,COUNT(*) AS position FROM t WHERE name <= 'search string' ORDER BY namefuente
Tengo problemas similares en los que necesito el rango ( índice ) de la tabla
order by votes desc. Lo siguiente funciona bien para mí.Select *, ROW_NUMBER() OVER(ORDER BY votes DESC) as "rank" From "category_model" where ("model_type" = ? and "category_id" = ?)fuente
puede ser lo que necesita es agregar sintaxis
así que usa
SELECT * FROM tbl ORDER BY name ASC LIMIT 1si solo necesitas una fila ...
fuente