usuario una son sirven que para nueva mostrar lugar las galerías fuente fragmento etiquetas entrada cómo cuáles cuales crear con completa añadir php mysql sql database group-by

php - una - Cómo agrupar por orden DESC



¿cómo crear una entrada con galerías en wordpress? (6)

Estoy escribiendo esta respuesta porque la primera / más corta alternativa de @ Taryn en respuesta aceptada funciona solo si está seleccionando exactamente solo las columnas utilizadas en GROUP BY y MAX. El usuario que pregunta es seleccionando todas las columnas en la tabla (él usó SELECCIONAR *). Entonces, cuando agrega otra tercera columna a la tabla, el valor de esa columna en el resultado de la consulta será incorrecto. Obtendrá valores mixtos de diferentes filas de la tabla. La segunda / más alternativa de @ Taryn (utilizando la unión interna y la subconsulta) funciona pero la consulta es inútilmente complicada y es 5 veces más lenta en mi caso de uso que mi alternativa simple a continuación.

Considere las questions mesa:

id | asker ----------- 1 | Bob 2 | Bob 3 | Marley

Consulte SELECT max(id) as id, asker FROM questions GROUP BY asker ORDER BY id DESC devuelve lo esperado :

id | asker ----------- 3 | Marley 2 | Bob

Ahora considere otras questions mesa:

id | asker | other ------------------- 1 | Bob | 1st 2 | Bob | 2nd 3 | Marley | 3rd

Consulte SELECT max(id) as id, asker, other FROM questions GROUP BY asker ORDER BY id DESC devuelve inesperado :

id | asker | other ------------------- 3 | Marley | 3rd 2 | Bob | 1st

... tenga en cuenta que el valor de other para la segunda fila del resultado es incorrecto porque id=2 proviene de la segunda fila de la tabla, pero other=1st proviene de la primera fila de la tabla! Así es como muchos usuarios en los comentarios de las respuestas de Taryn informan que esta solución no funciona.

Una posible solución simple al seleccionar también otras columnas es usar GROUP BY + DESC :

SELECT id, asker, other FROM questions GROUP BY asker DESC

id | asker | other ------------------- 3 | Marley | 3rd 2 | Bob | 2nd

(ver demostración: https://www.db-fiddle.com/f/esww483qFQXbXzJmkHZ8VT/10 )

... pero esta solución simple tiene algunas limitaciones:

  • La tabla debe ser InnoDB (creo que no es un problema porque obtendrá un mejor rendimiento y también desde que MySQL> = 5.5.5 el motor de almacenamiento predeterminado / preferido se cambió de MyISAM a InnoDB)
  • Debe crear el índice para la columna que se usa en GRUPO POR: así que el que asker en este caso (creo que no es un problema porque obtendrá un mejor rendimiento, ya que el índice es adecuado en este caso. GRUPO POR normalmente necesita la creación de la tabla tmp, pero cuando el índice está disponible (no se creará la tabla tmp, que es más rápida)
  • Para MySQL 5.7 y 8.0 es necesario deshabilitar el modo SQL ONLY_FULL_GROUP_BY (por ejemplo, SET SESSION sql_mode = ''''; ) o usar ANY_VALUE() en las columnas seleccionadas que no se agregan para evitar el error ER_WRONG_FIELD_WITH_GROUP.
  • Desafortunadamente, los desarrolladores de MySQL eliminaron el soporte de ASC / DESC dentro de GROUP BY desde MySQL 8.0 https://dev.mysql.com/worklog/task/?id=8693 pero, afortunadamente, existe una alternativa de GROUP BY col1 ORDER BY col1 ASC/DESC :

SELECT id, asker, other FROM questions GROUP BY asker ORDER BY asker DESC

id | asker | other ------------------- 3 | Marley | 3rd 2 | Bob | 2nd

(Ver demostración: https://www.db-fiddle.com/f/esww483qFQXbXzJmkHZ8VT/11 )

... el resultado es el mismo que el anterior con GROUP BY ... DESC (no olvide utilizar InnoDB y crear índice).

Tengo la siguiente tabla llamada preguntas:

ID | asker 1 | Bob 2 | Bob 3 | Marley

Quiero seleccionar cada persona que pregunta solo una vez y, si hay varias personas con el mismo nombre, seleccione la que tenga el ID más alto. Por lo tanto, los resultados esperados:

ID | asker 3 | Marley 2 | Bob

Yo uso la siguiente consulta:

SELECT * FROM questions GROUP by questions.asker ORDER by questions.id DESC

Obtengo el siguiente resultado:

ID | asker 3 | Marley 1 | Bob

Así que selecciona el primer ''Bob'' que encuentra en lugar del último.

Gracias


Los demás tienen razón al usar MAX (ID) para obtener los resultados que desea. Si se está preguntando por qué su consulta no funciona, es porque ORDER BY ocurre después de GROUP BY .


Los registros deben agruparse utilizando GROUP BY y MAX() para obtener el ID máximo para cada persona que asker .

SELECT asker, MAX(ID) ID FROM TableName GROUP BY asker

SALIDA

╔════════╦════╗ ║ ASKER ║ ID ║ ╠════════╬════╣ ║ Bob ║ 2 ║ ║ Marley ║ 3 ║ ╚════════╩════╝


Normalmente MySQL permite agrupar solo por registros de orden ascendente. Así podemos ordenar los registros antes de agruparlos.

SELECT * FROM ( SELECT * FROM questions ORDER BY id DESC ) AS questions GROUP BY questions.asker


Para obtener cada columna:

SELECT * FROM questions WHERE id IN (SELECT max(id) as id, asker FROM questions GROUP by asker ORDER by id DESC)

Versión mejorada de la respuesta de @bluefeet.


Si desea la última id para cada solicitante, debe utilizar una función agregada:

SELECT max(id) as id, asker FROM questions GROUP by asker ORDER by id DESC

La razón por la que estaba obteniendo el resultado inusual es porque MySQL usa una extensión a GROUP BY que permite que los elementos de una lista de selección no estén agregados y no estén incluidos en la cláusula GROUP BY. Sin embargo, esto puede llevar a resultados inesperados porque MySQL puede elegir los valores que se devuelven. (Ver Extensiones MySQL a GROUP BY )

De los documentos de MySQL:

MySQL extiende el uso de GROUP BY para que la lista de selección pueda hacer referencia a columnas no agregadas que no se mencionan en la cláusula GROUP BY. ... Puede utilizar esta función para obtener un mejor rendimiento al evitar la ordenación y agrupación innecesarias de columnas. Sin embargo, esto es útil principalmente cuando todos los valores en cada columna no agregada no nombrados en el GRUPO POR son iguales para cada grupo. El servidor es libre de elegir cualquier valor de cada grupo, por lo tanto, a menos que sean iguales, los valores elegidos son indeterminados. Además, la selección de valores de cada grupo no puede verse influida por la adición de una cláusula ORDER BY. La clasificación del conjunto de resultados se produce después de que se hayan elegido los valores, y ORDER BY no afecta a qué valores elige el servidor.

Ahora, si tenía otras columnas que necesita regresar de la tabla, pero no desea agregarlas a GROUP BY debido a los resultados inconsistentes que podría obtener, entonces podría usar una subconsulta para hacerlo. ( Demo )

select q.Id, q.asker, q.other -- add other columns here from questions q inner join ( -- get your values from the group by SELECT max(id) as id, asker FROM questions GROUP by asker ) m on q.id = m.id order by q.id desc