@AlirezaSoori: A pesar del nombre, ides solo una columna en una tabla. No hay garantía de que los valores en la idcolumna tengan que ser únicos.
unutbu
1
@unutbu Suponiendo que idno es una clave primaria o única :) Dado el nombre, existe una posibilidad razonable de que lo sea. También vale la pena señalar que, dependiendo del DBMS que esté utilizando, el enfoque con la subselección puede ser mucho menos eficiente.
Michael Mior
3
@MichaelMior: idpodría ser una clave externa, en cuyo caso puede no ser única. Hice algunos benchmarking usando set profiling = 1; ...; show profilesy parece que nuestras soluciones tienen el mismo rendimiento usando MySQL. Que yo sepa, ¿sabe qué DBMS tiene un rendimiento inferior para las subselecciones?
unutbu
1
Podría ser una clave foránea, pero como dije, solo estoy adivinando en base al nombre que no lo es. Históricamente, se sabe que MySQL tiene un mal rendimiento con subselecciones. Sin embargo, eso ha mejorado enormemente en las versiones más nuevas, por lo que depende de la versión que esté utilizando. Sin embargo, reconsiderándolo, esta consulta particular puede estar bien. Aunque ejecutar una consulta un par de veces con la creación de perfiles no necesariamente dice mucho sobre el rendimiento relativo.
Michael Mior
149
También podrías hacer
SELECTrowFROMtableORDERBY id DESC LIMIT 1;
Esto ordenará las filas por su ID en orden descendente y devolverá la primera fila. Esto es lo mismo que devolver la fila con la ID máxima. Por supuesto, esto supone que ides único entre todas las filas. De lo contrario, podría haber varias filas con el valor máximo para idy solo obtendrá una.
Para hacer específicamente lo que el OP está pidiendo, haría esto. Pero las otras respuestas proporcionan una mejor educación sobre la estructura SQL :)
MatBailie
@Dems ¿Cómo es eso? ¿No se dan explicaciones sobre ninguna otra respuesta? Por supuesto, también soy culpable de eso :(
Michael Mior
Solo que otras preguntas corrigen la sintaxis sin refactorizar la lógica. Entonces, el OP aprende cómo establecer ese sql específico correctamente.
MatBailie
Punto justo :) Aunque posiblemente otras respuestas todavía están corrigiendo la lógica.
Michael Mior
¿Qué pasa con el rendimiento? Llegué aquí con este tipo de consulta que ya funcionaba para mí, pero me preguntaba si esa es la forma correcta. ¿ORDER BY no es una operación O (n * log n)?
dhill
27
SELECT*FROMtableWHERE id =(SELECT MAX(id)FROMTABLE)
@ shA.no SELECT entry FROM table WHERE id = MAX(id)funcionaría ?!
oldboy
@ shA.t Además, estoy tratando de hacer algo como lo siguiente: SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified WHERE account_email = :account_email)por el cual solo necesito la entry_timeentrada más reciente en la base de datos. ¿Es esa declaración suficiente o debería ser:SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified) AND account_email = :account_email
oldboy
No existe un significado confiable para la entrada más reciente en el resultado de una consulta, debe tener un campo para el tiempo de inserción, etc. Por cierto, por favor haga su pregunta por separado, espero que reciba más atención -HTH;).
shA.t
17
No se puede dar order byporque order byhace un "escaneo completo" en una mesa.
La siguiente consulta es mejor:
SELECT*FROMtableWHERE id =(SELECT MAX(id)FROMtable);
ORDER BYno realizará un análisis completo si supone que esa ides la clave principal de la tabla. (Y si no lo es, tiene un nombre bastante pobre). Si no lo es, ¿cómo espera MAX(id)trabajar sin un escaneo completo de la tabla? Si no hay índice, todos los valores deben ser verificados para encontrar el máximo.
Michael Mior
@CakeLikeBoss bueno, realmente intenté "ordenar por" consulta y su "SELECT * FROM table WHERE id = (SELECT MAX (id) FROM table);" consulta sobre una mesa de 114 filas, mientras que esta consulta se llevó exactamente 0,0004 segundos cada vez, mientras que la segunda consulta tomó de 0,0007 a 0,0010 segundos repetí varias veces
prabhjot
1
Siempre se pueden elegir funciones analíticas, lo que le dará más control.
select tmp.row from ( select row, rank() over(partition by id order by id desc ) as rnk from table) tmp where tmp.rnk=1
Si tiene problemas con la función rank () dependiendo del tipo de datos, entonces también puede elegir entre row_number () o dense_rank ().
La palabra clave TOP no funciona en MySQL. Esta consulta no funcionará.
Anirudha Gupta
@toddmo: MySQL! Y Sql-Server tampoco es útil para otras personas. ¿Te refieres a MS-SQL?
Raiserle
@raiserle, ¿puedes ayudarme a encontrar dónde comenté o publiqué algo sobre esta pregunta? No puedo ver mi nombre adjunto a esta pregunta en ninguna parte.
Respuestas:
Podría usar una subselección:
Tenga en cuenta que si el valor de
max(id)
no es único, se devuelven varias filas.Si solo desea una de esas filas, use la respuesta de @ MichaelMior,
fuente
id
es solo una columna en una tabla. No hay garantía de que los valores en laid
columna tengan que ser únicos.id
no es una clave primaria o única :) Dado el nombre, existe una posibilidad razonable de que lo sea. También vale la pena señalar que, dependiendo del DBMS que esté utilizando, el enfoque con la subselección puede ser mucho menos eficiente.id
podría ser una clave externa, en cuyo caso puede no ser única. Hice algunos benchmarking usandoset profiling = 1; ...; show profiles
y parece que nuestras soluciones tienen el mismo rendimiento usando MySQL. Que yo sepa, ¿sabe qué DBMS tiene un rendimiento inferior para las subselecciones?También podrías hacer
Esto ordenará las filas por su ID en orden descendente y devolverá la primera fila. Esto es lo mismo que devolver la fila con la ID máxima. Por supuesto, esto supone que
id
es único entre todas las filas. De lo contrario, podría haber varias filas con el valor máximo paraid
y solo obtendrá una.fuente
fuente
SELECT entry FROM table WHERE id = MAX(id)
funcionaría ?!SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified WHERE account_email = :account_email)
por el cual solo necesito laentry_time
entrada más reciente en la base de datos. ¿Es esa declaración suficiente o debería ser:SELECT entry_time FROM users_unverified WHERE num_id = (SELECT MAX(num_id) FROM users_unverified) AND account_email = :account_email
No se puede dar
order by
porqueorder by
hace un "escaneo completo" en una mesa.La siguiente consulta es mejor:
fuente
ORDER BY
no realizará un análisis completo si supone que esaid
es la clave principal de la tabla. (Y si no lo es, tiene un nombre bastante pobre). Si no lo es, ¿cómo esperaMAX(id)
trabajar sin un escaneo completo de la tabla? Si no hay índice, todos los valores deben ser verificados para encontrar el máximo.Siempre se pueden elegir funciones analíticas, lo que le dará más control.
select tmp.row from ( select row, rank() over(partition by id order by id desc ) as rnk from table) tmp where tmp.rnk=1
Si tiene problemas con la función rank () dependiendo del tipo de datos, entonces también puede elegir entre row_number () o dense_rank ().
fuente
Intenta con esto
fuente