Sql server con consultas Limit de mySQL

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)

Sobre Asier

Arquitecto web enganchado al desarrollo, estudio y planteamiento de proyectos en internet. Trabajo en Blackslot, empresa que fundé en el 2009. Me encanta el cine, el café, el sexo, la cultura geek, la cultura oriental y la música electrónica.
Artículo publicado en Bases de Datos, Microsoft, Sistemas. Enlace a esta entrada..

14 espuestas a Sql server con consultas Limit de mySQL

  1. gubatron dijo:

    Te compadezco por tener que lidiar con SQL Server.

  2. Jajaja bueno estoy con la 2005… las otras me dan escalofrios :P
    Por cierto, felicidades por la boda!! :D

  3. Pingback: Oracle con consultas Limit de mySQL

  4. German dijo:

    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.

  5. Ronald Leon dijo:

    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
    ——————————————–

  6. germanach dijo:

    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;

  7. Rolf Pinto dijo:

    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

  8. Lila dijo:

    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);

  9. Pingback: Paginar resultados en SQL Server 2000, al estilo Limit de mySQL

  10. Santos dijo:

    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.

  11. rsolaz dijo:

    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.

  12. rsolaz dijo:

    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.

  13. Peter dijo:

    ¡Muchas gracias! Me ha sido muy útil

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos requeridos, están marcados *

*

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notificarme los nuevos comentarios por correo electrónico. Tambien puedes suscribirte sin comentar.