En mySql tenemos una opción para las consultas Select que nos permite decirle a la base de datos que devuelva un rango de resultados deseados en vez de todos lo que puede devolver dicha consulta Select. Por ejemplo una consulta con Limit sería:
Select * from tabla Limit 4,8
Esto nos devuelve un rango de 8 resultados desde el 4º encontrado (ideal para paginaciones)
En sqlServer no disponemos de la opción Limit, por lo que debemos usar la opción ROW_NUMBER() OVER y asignarlo a un alias, como vemos en la siguiente consulta:
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY id) as row FROM tabla ) as alias WHERE row > 4 and row <= 12
Esto nos devuelve un rango de 8 resultados desde el 4º encontrado (el rango estaría especificado entre 8 y 12)
Te compadezco por tener que lidiar con SQL Server.
Jajaja bueno estoy con la 2005… las otras me dan escalofrios :P
Por cierto, felicidades por la boda!! :D
Pingback: Oracle con consultas Limit de mySQL
germanachar(at)yahoo(dot)com(dot)ar
Sabe si esta consulta es compatible con el estandar SQL92?
Sino, como podria hacer una consulta utilizando subconsultas que emulen LIMIT x,y?
Sin usar vistas ni tablas auxiliares ni with.
Existe una forma de obtener el mismo resultado de las funciones Limit y Offset de MYSQL y Postgre en SQL Server, sin necesidad de estar creando Stored Procedure del lado servidor, los cuales retrasan los tiempos de respuestas
motivado a la creación de tablas temporales a fin de crear un Index propio el cual sevirá de referencia para la busqueda.
Esta función es de facil manejo simplemente retorna un SQLquery adaptado a nuestra necesidad, y los únicos parámetros exigidos es el SQL de nuestra consulta, el campo clave de la misma, la pagina a visualizar y por último la cantidad de registro por página.
El código es el siguiente, esta desarrollado en Visual Basic sin embargo su adaptación a caulquier lenguaje será sencilla:
———————————————–
Function SQLpaginar(SQL As String, Clave As String, Pagina As Integer, Cantidad As Integer)
If Pagina > 0 And Cantidad > 0 And Clave “” Then
Dim Fsql As String, Dsql As String, Asql As String
Fsql = “SELECT TOP ” & Pagina * Cantidad & ” * FROM (” & SQL & “) DERIVEDTBL”
Dsql = “SELECT TOP ” & Cantidad & ” * FROM (” & Fsql & “) DERIVEDTBL ORDER BY ” & Clave & ” DESC”
Asql = “SELECT TOP ” & Cantidad & ” * FROM (” & Dsql & “) DERIVEDTBL ORDER BY ” & Clave & ” ASC”
SQLpaginar = Asql
Else
SQLpaginar = SQL
End If
End Function
——————————————–
Esa respuesta, al menos a mi no me sirve. Hice la pregunta y traigo la respuesta.
Una sub – consulta SQL92 estandar que limita una busqueda a una cierta cantidad de resultados para mi esquema de empresa de transporte (si alguien puede explicar en que orden se va haciendo la consulta?) es la siguiente. (Esto no es tan facil de encontrar, guardenla!):
## FIGURITA DIFICIL. Consulta estandar SQL92
## que limita los resultados de una consulta
select (
select count(*) from servicio s1
where s1.patente <= s2.patente) as fila, patente
from servicio s2
where(
select count(*) from servicio s1
where s1.patente <= s2.patente)<=5
order by patente desc;
Muy buena solución, muchas gracias al final puede quedar así:
ALTER PROCEDURE [dbo].[litapaginada]
@startRow int,
@maxRow int
AS
BEGIN
SELECT * FROM (
SELECT ROW_NUMBER() OVER (ORDER BY idxxx) as ‘idfila’ , * FROM tabla
) as tabla
WHERE idfila @startRow 1 and @maxRow
END
Alguien me puede “traducir” esto a mssql usando TOP?
mssql_select_db($database_conectionx, $conectionx);
$query_work = “SELECT status, COUNT(*) AS status2 FROM quotex WHERE status LIKE ‘%work%’ AND [average response time]=2008 GROUP BY status”;
$query_limit_work = sprintf(“%s LIMIT %d, %d”, $query_work, $startRow_work, $maxRows_work);
$work = mssql_query($query_limit_work, $conectionx) or die(“error”);
$row_work = mssql_fetch_assoc($work);
@lila echa un vistazo a mi último post http://asiermarques.com/2009/01/27/paginar-resultados-en-sql-server-2000-al-estilo-limit-de-mysql/
Pingback: Paginar resultados en SQL Server 2000, al estilo Limit de mySQL
Buenas Asier, muchísimas gracias por tu post, me ha sido de gran ayuda, pero tengo un problemilla, a ver si me puedes echar una mano.
Utilizo esta consulta como tu bien has explicado:
“SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY CodArticulo) as row FROM Articulos ) as alias WHERE row > $startRow_ver_destacados AND row <=$endRow_ver_destacados AND EsDestacado= 0″
$starRow indica desde donde empiezo y $endRow hasta donde llego. En este caso pagino 16 registros por cada página ok?. El problema es que cuando en la pagina hay registros que no cumplen las caracteristicas de la consulta (pejem Esdestaco =1 en vez de 0) en vez de quitarme el registro (no debe mostrarlo puesto que no cumple las caracteristicas de la consulta) y continuar con el siguiente lo que hace esque me deja el hueco de ese registro al final de la pagina. Así sucede en cada página donde hay registros que no coinciden con las especificaciones de la consulta. Es como que en SQL coge los 16 por página cumplan o no cumplan las especificaciones, mientras que en mysql lo hago y va perfectamente entran los 16 primeros registros que cumplan las especificaciones.
La verdad que no si me he explicado con claridad.
Un saludo.
Hola, es un poco tarde la respuesta, pero po si alguien le puede servir.
Es para el ultimo comentario de Santos. Pon la condicion dentro de la subconsulta, es decir:
“SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY CodArticulo) as row FROM Articulos WHERE EsDestacado=0) as alias WHERE row > $startRow_ver_destacados AND row inicio and row<=fin
Espero haberme explicado.
Saludos.
Perdonar pero me ha cortado el comentario, no entiendo. PEgo la consulta correcta:
“SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY CodArticulo) as row FROM Articulos WHERE EsDestacado=0) as alias WHERE row > $startRow_ver_destacados”
Lo que quieria decir era que primero se filtra en la subconsulta y se ordena el resultado del filtro(subconsulta) y despues con el select externo es con el que se hace el “limit” se eligen que registros (numeros de fila) de todo el resultado queremos que salgan.
¡Muchas gracias! Me ha sido muy útil