Pregunta

Estoy interesado en el aprendizaje de algunos (idealmente) de la base de datos agnóstico formas de seleccionar el nth fila de una tabla de base de datos.También sería interesante ver cómo esto puede lograrse mediante la funcionalidad nativa de las siguientes bases de datos:

  • SQL Server
  • MySQL
  • PostgreSQL
  • SQLite
  • Oracle

Actualmente estoy haciendo algo como lo siguiente en SQL Server 2005, pero estaría interesado en ver a otros más agnóstico enfoques:

WITH Ordered AS (
SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS RowNumber, OrderID, OrderDate
FROM Orders)
SELECT *
FROM Ordered
WHERE RowNumber = 1000000

Crédito de la anterior de SQL: Firoz Ansari Weblog

Actualización: Ver Troels Arvin la respuesta con respecto al estándar SQL. Troels, tienes los enlaces podemos citar?

¿Fue útil?

Solución

Hay maneras de hacer esto en partes opcionales de la norma, sino una gran cantidad de bases de datos de apoyo a su propia manera de hacerlo.

Un sitio muy bueno que habla sobre esto y otras cosas es http://troels.arvin.dk/db/rdbms/#select-limit.

Básicamente, PostgreSQL y MySQL soporta la no-estándar:

SELECT...
LIMIT y OFFSET x 

Oracle, DB2 y MSSQL admite el estándar de ventanas de funciones:

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,
    columns
  FROM tablename
) AS foo
WHERE rownumber <= n

(que he copiado del sitio enlazado más arriba ya que yo nunca uso los DBs)

Actualización: Como de PostgreSQL 8.4 el estándar de ventanas funciones son compatibles, por lo que esperan que en el segundo ejemplo de trabajo para PostgreSQL así.

Actualización: SQLite agregado las funciones de la ventana de soporte en la versión 3.25.0 en 2018-09-15 por lo tanto formas de trabajar también en SQLite.

Otros consejos

El LIMIT / OFFSET la sintaxis en PostgreSQL es:

SELECT
    *
FROM
    mytable
ORDER BY
    somefield
LIMIT 1 OFFSET 20;

En este ejemplo se selecciona el 21 de fila. OFFSET 20 está diciendo Postgres para pasar los primeros 20 registros.Si no se especifica un ORDER BY la cláusula, no hay ninguna garantía de que se registre recibirá de vuelta, que rara vez es útil.

Al parecer, el estándar SQL no se pronuncia sobre el tema límite exterior de la loca de ventanas de funciones, que es por qué todo el mundo lleva a cabo de manera diferente.

No estoy seguro acerca de cualquier de los demás, pero sé SQLite y MySQL no tengo ningún "defecto" ordenación de las filas.En los dos dialectos, al menos, el siguiente fragmento de código se agarra el 15 de entrada de the_table, ordenar por la fecha/hora en que fue añadido:

SELECT * FROM the_table ORDER BY added DESC LIMIT 1,15

(por supuesto, tendría que haber añadido campo DATETIME, y establezca la fecha y la hora en que la entrada fue añadido...)

SQL 2005 y encima tiene esta característica incorporada.Uso de la función ROW_NUMBER ().Es excelente para páginas web con una << Prev y Next >> estilo de navegación:

Sintaxis:

SELECT
    *
FROM
    (
        SELECT
            ROW_NUMBER () OVER (ORDER BY MyColumnToOrderBy) AS RowNum,
            *
        FROM
            Table_1
    ) sub
WHERE
    RowNum = 23

Sospecho que esto es tremendamente ineficaz, pero es un enfoque simple, que trabajó en un pequeño conjunto de datos que he probado.

select top 1 field
from table
where field in (select top 5 field from table order by field asc)
order by field desc

Esto obtendría el 5to elemento, cambiar el segundo número de arriba para obtener una enésimo elemento

Sólo en SQL server (creo), pero debería funcionar en las versiones antiguas que no admiten ROW_NUMBER().

Verificar que en SQL Server:

Select top 10 * From emp 
EXCEPT
Select top 9 * From emp

Esto le dará 10 de FILA de la tabla emp!

1 pequeño cambio:n-1 en lugar de n.

select *
from thetable
limit n-1, 1

Contrariamente a lo que algunas de las respuestas de reclamación, el estándar SQL no está en silencio con respecto a este tema.

Desde SQL:2003, han sido capaces de utilizar la ventana "funciones" para saltar filas y limitar los conjuntos de resultados.

Y en SQL:2008, una ligeramente más sencillo planteamiento se había añadido, el uso de
OFFSET skip ROWS FETCH FIRST n ROWS ONLY

Personalmente, no creo que SQL:2008 además era realmente necesario, así que si yo fuera ISO, me han mantenido fuera de un lugar ya de gran tamaño estándar.

Oracle:

select * from (select foo from bar order by foo) where ROWNUM = x

Cuando hemos utilizado para trabajar en MSSQL 2000, hicimos lo que hemos llamado la "triple flip":

EDITADO

DECLARE @InnerPageSize int
DECLARE @OuterPageSize int
DECLARE @Count int

SELECT @Count = COUNT(<column>) FROM <TABLE>
SET @InnerPageSize = @PageNum * @PageSize
SET @OuterPageSize = @Count - ((@PageNum - 1) * @PageSize)

IF (@OuterPageSize < 0)
    SET @OuterPageSize = 0
ELSE IF (@OuterPageSize > @PageSize)
    SET @OuterPageSize = @PageSize

DECLARE @sql NVARCHAR(8000)

SET @sql = 'SELECT * FROM
(
    SELECT TOP ' + CAST(@OuterPageSize AS nvarchar(5)) + ' * FROM
    (
        SELECT TOP ' + CAST(@InnerPageSize AS nvarchar(5)) + ' * FROM <TABLE> ORDER BY <column> ASC
    ) AS t1 ORDER BY <column> DESC
) AS t2 ORDER BY <column> ASC'

PRINT @sql
EXECUTE sp_executesql @sql

No era elegante, y no era rápido, pero funcionó.

SQL SERVER


Seleccione n' th registro de arriba

SELECT * FROM (
SELECT 
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID) AS ROW
FROM TABLE 
) AS TMP 
WHERE ROW = n

seleccione n' th registro de la parte inferior

SELECT * FROM (
SELECT 
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID DESC) AS ROW
FROM TABLE 
) AS TMP 
WHERE ROW = n

Aquí es una solución rápida y de su confusión.

SELECT * FROM table ORDER BY `id` DESC LIMIT N, 1

Aquí Usted puede conseguir la Última fila por el Llenado de N=0, Segunda y última por N=1, Cuarto Último Mediante la Cumplimentación de N=3 y así sucesivamente.

Esto es muy común la pregunta sobre la entrevista y esto es Muy simple ans de ella.

Si usted desea Cantidad, ID o algunos Numérico de Ordenación de u puede ir para el ELENCO de la función en MySQL.

SELECT DISTINCT (`amount`) FROM cart ORDER BY CAST( `amount` AS SIGNED ) DESC LIMIT 4 , 1

Aquí rellenando N = 4 Usted será capaz de obtener la Quinta Último Récord de Mayor Cantidad de CARRITO de la tabla.Puede adaptarse a su campo y el nombre de la tabla y llegar a la solución.

AGREGAR:

LIMIT n,1

Que va a limitar los resultados a un resultado comenzando el resultado n.

Por ejemplo, si desea seleccionar una de cada 10 fila en MSSQL, usted puede usar;

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY ColumnName1 ASC) AS rownumber, ColumnName1, ColumnName2
  FROM TableName
) AS foo
WHERE rownumber % 10 = 0

Acaba de tomar el MOD y el número de cambio de 10 aquí cualquier número que desee.

LÍMITE de n,1 no funciona en MS SQL Server.Creo que solo se trata de la única gran base de datos que no sea compatible con la sintaxis.Para ser justos, no es parte del estándar SQL, aunque es ampliamente admitido que debería ser.En todo excepto en SQL server LÍMITE de las grandes obras.Para SQL server, no he sido capaz de encontrar una solución elegante.

He aquí una versión genérica de un procedimiento almacenado que me escribió recientemente por Oracle que permite la dinámica de paginación/clasificación - HTH

-- p_LowerBound = first row # in the returned set; if second page of 10 rows,
--                this would be 11 (-1 for unbounded/not set)
-- p_UpperBound = last row # in the returned set; if second page of 10 rows,
--                this would be 20 (-1 for unbounded/not set)

OPEN o_Cursor FOR
SELECT * FROM (
SELECT
    Column1,
    Column2
    rownum AS rn
FROM
(
    SELECT
        tbl.Column1,
        tbl.column2
    FROM MyTable tbl
    WHERE
        tbl.Column1 = p_PKParam OR
        tbl.Column1 = -1
    ORDER BY
        DECODE(p_sortOrder, 'A', DECODE(p_sortColumn, 1, Column1, 'X'),'X'),
        DECODE(p_sortOrder, 'D', DECODE(p_sortColumn, 1, Column1, 'X'),'X') DESC,
        DECODE(p_sortOrder, 'A', DECODE(p_sortColumn, 2, Column2, sysdate),sysdate),
        DECODE(p_sortOrder, 'D', DECODE(p_sortColumn, 2, Column2, sysdate),sysdate) DESC
))
WHERE
    (rn >= p_lowerBound OR p_lowerBound = -1) AND
    (rn <= p_upperBound OR p_upperBound = -1);

Pero realmente, ¿todo esto no es realmente sólo trucos de salón para un buen diseño de base de datos en el primer lugar?Las pocas veces que me la funcionalidad necesaria como esta fue para un simple fuera de la consulta para realizar un informe rápido.Para cualquier trabajo real, el uso de trucos como estos es invitar a los problemas.Si se selecciona una fila en particular es necesario, a continuación, sólo tiene una columna con un valor secuencial y hacer con ella.

En Oracle 12c, Usted puede usar OFFSET..FETCH..ROWS opción con ORDER BY

Por ejemplo, para obtener el 3er registro de arriba:

SELECT * 
FROM   sometable
ORDER BY column_name
OFFSET 2 ROWS FETCH NEXT 1 ROWS ONLY;

En Sybase SQL Anywhere:

SELECT TOP 1 START AT n * from table ORDER BY whatever

No olvides que la ORDEN o no tiene sentido.

T-SQL - Selección de los N-ésimos RecordNumber de una Tabla

select * from
 (select row_number() over (order by Rand() desc) as Rno,* from TableName) T where T.Rno = RecordNumber

Where  RecordNumber --> Record Number to Select
       TableName --> To be Replaced with your Table Name

Por ejemplo,para seleccionar 5 º registro de una tabla de Empleados, la consulta debe ser

select * from
 (select row_number() over (order by Rand() desc) as Rno,* from Employee) T where T.Rno = 5
SELECT * FROM emp a
WHERE  n = (SELECT COUNT( _rowid)
              FROM emp b
             WHERE a. _rowid >= b. _rowid);
SELECT
    top 1 *
FROM
    table_name
WHERE
    column_name IN (
        SELECT
            top N column_name
        FROM
            TABLE
        ORDER BY
            column_name
    )
ORDER BY
    column_name DESC

He escrito esta consulta para encontrar Enésima fila.Ejemplo con esta consulta sería

SELECT
    top 1 *
FROM
    Employee
WHERE
    emp_id IN (
        SELECT
            top 7 emp_id
        FROM
            Employee
        ORDER BY
            emp_id
    )
ORDER BY
    emp_id DESC

Para SQL Server, una forma genérica para ir por el número de fila es como tal:

SET ROWCOUNT @row --@row = the row number you wish to work on.

Por Ejemplo:

set rowcount 20   --sets row to 20th row

select meat, cheese from dbo.sandwich --select columns from table at 20th row

set rowcount 0   --sets rowcount back to all rows

Esto devolverá el 20 de fila de la información.Asegúrese de poner en el recuento de 0 después.

increíble que usted puede encontrar un motor de SQL ejecución de este ...

WITH sentence AS
(SELECT 
    stuff,
    row = ROW_NUMBER() OVER (ORDER BY Id)
FROM 
    SentenceType
    )
SELECT
    sen.stuff
FROM sentence sen
WHERE sen.row = (ABS(CHECKSUM(NEWID())) % 100) + 1

Nada de lujo, no hay funciones especiales, en el caso de utilizar Caché como tengo que hacer...

SELECT TOP 1 * FROM (
  SELECT TOP n * FROM <table>
  ORDER BY ID Desc
)
ORDER BY ID ASC

Dado que disponemos de una columna de ID o un datestamp columna que usted puede confiar.

Así es como yo lo haría dentro de DB2 SQL, creo que la RRN relativa (número de registro) se almacenan en la tabla de la O/S;

SELECT * FROM (                        
   SELECT RRN(FOO) AS RRN, FOO.*
   FROM FOO                         
   ORDER BY RRN(FOO)) BAR             
 WHERE BAR.RRN = recordnumber
select * from 
(select * from ordered order by order_id limit 100) x order by 
x.order_id desc limit 1;

Primero seleccione top 100 filas al ordenar en forma ascendente y, a continuación, seleccione la última fila por orden decreciente y limitar a 1.Sin embargo, esto es muy costoso declaración como acceder a los datos dos veces.

A mí me parece que, para ser eficaz, necesita 1) generar un número aleatorio entre 0 y uno menos que el número de registros de base de datos, y 2) ser capaz de seleccionar la fila en esa posición.Por desgracia, las diferentes bases de datos tienen diferentes generadores de números aleatorios y diferentes maneras de seleccionar una fila en una posición en un conjunto de resultados - por lo general se especifique el número de filas para saltar y la cantidad de filas que desea, pero se realiza de forma diferente para diferentes bases de datos.Aquí es algo que me funciona en SQLite:

select * 
from Table 
limit abs(random()) % (select count(*) from Words), 1;

No depende de ser capaz de utilizar una subconsulta en la cláusula limit (que en SQLite es el LÍMITE <recs to="" skip="">,<recs to="" take="">) Seleccionar el número de registros de una tabla debe ser especialmente eficiente, se parte de la base de datos de los meta-datos, sino que depende de la base de datos de la aplicación.También, no sé si la consulta va a construir el conjunto de resultados antes de recuperar el Enésimo récord, pero yo espero que no necesita.Tenga en cuenta que no soy la especificación de una cláusula "order by".Podría ser mejor para "ordenar por", algo así como la clave principal, que tiene un índice de obtener los N registros de un índice puede ser más rápido si la base de datos no puede obtener los N registros de la base de datos sin necesidad de construir el conjunto de resultados.

Para SQL server, el siguiente se devuelve la primera fila de darle la tabla.

declare @rowNumber int = 1;
    select TOP(@rowNumber) * from [dbo].[someTable];
EXCEPT
    select TOP(@rowNumber - 1) * from [dbo].[someTable];

Puede crear un bucle a través de los valores con algo como esto:

WHILE @constVar > 0
BEGIN
    declare @rowNumber int = @consVar;
       select TOP(@rowNumber) * from [dbo].[someTable];
    EXCEPT
       select TOP(@rowNumber - 1) * from [dbo].[someTable];  

       SET @constVar = @constVar - 1;    
END;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top