¿Cómo uso ROW_NUMBER ()?

175

Quiero usar el ROW_NUMBER()para obtener ...

  1. Para obtener el max(ROW_NUMBER())-> O supongo que esto también sería el recuento de todas las filas

Traté de hacer:

SELECT max(ROW_NUMBER() OVER(ORDER BY UserId)) FROM Users

pero no pareció funcionar ...

  1. Para obtener el ROW_NUMBER()uso de una determinada información, es decir. si tengo un nombre y quiero saber de qué fila proviene el nombre.

Supongo que sería algo similar a lo que intenté para el n. ° 1

SELECT ROW_NUMBER() OVER(ORDER BY UserId) From Users WHERE UserName='Joe'

pero esto tampoco funcionó ...

¿Algunas ideas?

gastador
fuente

Respuestas:

150

Para la primera pregunta, ¿por qué no solo usar?

SELECT COUNT(*) FROM myTable 

para obtener el recuento.

Y para la segunda pregunta, la clave principal de la fila es qué se debe usar para identificar una fila en particular. No intentes usar el número de fila para eso.


Si devolvió Row_Number () en su consulta principal,

SELECT ROW_NUMBER() OVER (Order by Id) AS RowNumber, Field1, Field2, Field3
FROM User

Luego, cuando desee ir 5 filas hacia atrás, puede tomar el número de fila actual y usar la siguiente consulta para determinar la fila con currentrow -5

SELECT us.Id
FROM (SELECT ROW_NUMBER() OVER (ORDER BY id) AS Row, Id
     FROM User ) us 
WHERE Row = CurrentRow - 5   
Darrel Miller
fuente
En mi situación, recibo un UserId y quiero recuperar el UserId que es un cierto número de filas. ¿Qué pasa si se elimina una fila? En ese caso, no puedo simplemente usar UserId - offset, porque entonces no obtendría el registro correcto.
Es mejor usar select count (1) de mytable para seleccionar el recuento de registros. Esto es tan rápido y eficiente
Sivajith
46

Aunque estoy de acuerdo con otros que podría usar count()para obtener el número total de filas, así es como puede usar el row_count():

  1. Para obtener el no total de filas:

    with temp as (
        select row_number() over (order by id) as rownum
        from table_name 
    )
    select max(rownum) from temp
  2. Para obtener los números de fila donde se llama Matt:

    with temp as (
        select name, row_number() over (order by id) as rownum
        from table_name
    )
    select rownum from temp where name like 'Matt'

Puede usar más min(rownum)o max(rownum)para obtener la primera o la última fila de Matt respectivamente.

Estas fueron implementaciones muy simples de row_number(). Puede usarlo para agrupaciones más complejas. Vea mi respuesta en Agrupación avanzada sin usar una subconsulta

Usuario SO
fuente
¿Podría explicar cómo elegir la columna utilizada order by X? En otras palabras, ¿cómo debe Xdeterminarse? ¡Gracias!
Kevin Meredith
@KevinMeredith: order by Xes el orden que usará para determinar el orden en que se asignarán las filas ROW_NUMBERS(). Recuerde que las tablas en bases de datos relacionales, a pesar de su nombre, no tienen un orden formal, por lo que si desea llamar a una fila "1" o "10" o "1337", primero debe ordenarlas mediante una ORDER BYcláusula, que es el que va en la OVER (ORDER BY X)cláusula
Wtrmute
25

Si necesita devolver el recuento total de filas de la tabla, puede usar una forma alternativa de la SELECT COUNT(*)declaración.

Debido a que SELECT COUNT(*)realiza un escaneo completo de la tabla para devolver el recuento de filas, puede llevar mucho tiempo para una tabla grande. Puede usar la sysindexestabla del sistema en este caso. Hay una ROWScolumna que contiene el recuento total de filas para cada tabla en su base de datos. Puede usar la siguiente instrucción select:

SELECT rows FROM sysindexes WHERE id = OBJECT_ID('table_name') AND indid < 2

Esto reducirá drásticamente el tiempo que toma su consulta.

Muhammad Akhtar
fuente
Tiene razón sobre el escaneo completo de la tabla, pero tenga en cuenta que no es necesariamente un escaneo de índice agrupado, ya que podría usar un índice no agrupado para eso
yoel halb
2
También esto es cierto solo para Sql-Server, ya que otros RDMBS han optimizado el recuento de selección
yoel halb
7

ROW_NUMBER() devuelve un número único para cada fila que comienza con 1. Puede usarlo fácilmente simplemente escribiendo:

ROW_NUMBER() OVER (ORDER BY 'Column_Name' DESC) as ROW_NUMBER

Se puede ver la diferencia entre Row_number(), Rank()y Dense_Rank() aquí .

Jatin Phulera
fuente
7

Puede usar esto para obtener el primer registro donde tiene cláusula

SELECT TOP(1) * , ROW_NUMBER() OVER(ORDER BY UserId) AS rownum 
FROM     Users 
WHERE    UserName = 'Joe'
ORDER BY rownum ASC
Omid Farvid
fuente
4
SELECT num, UserName FROM 
 (SELECT UserName, ROW_NUMBER() OVER(ORDER BY UserId) AS num
  From Users) AS numbered
WHERE UserName='Joe'
Alex Martelli
fuente
Para enumerar todas las filas; de lo contrario, solo está enumerando las filas donde el nombre de usuario es Joe, que no es el objetivo ;-).
Alex Martelli
1
@ Matt: Llámame pedante; Tiendo a preferir "tabla derivada" o "vista anónima" al término "subseleccionar".
mechanical_meat
1
@adam, como yo también soy pedante, ¿"select anidado" te haría más feliz? No me gusta que utilizan términos tales como tabla o la vista cuando no hay TABLEo VIEWpalabra clave es de alrededor ... pero SELECTseguro que es! -)
Alex Martelli
@ Alex: presenta un punto válido. "Selección anidada" funciona muy bien para mí :) Por cierto, realmente disfruto leyendo las anécdotas que agregas a tus comentarios y respuestas.
mechanical_meat
@ Adam, gracias! A veces mis respuestas son muy simples, como aquí, pero me encanta darlas a conocer cuando tengo un minuto libre ;-).
Alex Martelli
4

Puede no estar relacionado con la pregunta aquí. Pero descubrí que podría ser útil al usar ROW_NUMBER-

SELECT *,
ROW_NUMBER() OVER (ORDER BY (SELECT 100)) AS Any_ID 
FROM #Any_Table
Jyo
fuente
3
select 
  Ml.Hid,
  ml.blockid,
  row_number() over (partition by ml.blockid order by Ml.Hid desc) as rownumber,
  H.HNAME 
from MIT_LeadBechmarkHamletwise ML
join [MT.HAMLE] h on ML.Hid=h.HID
Hari Lakkakula
fuente
2

Si absolutamente quiere usar ROW_NUMBER para esto (en lugar de contar (*)), siempre puede usar:

SELECT TOP 1 ROW_NUMBER() OVER (ORDER BY Id)   
FROM USERS  
ORDER BY ROW_NUMBER() OVER (ORDER BY Id) DESC
Richard S
fuente
2

Puede usar Row_Numberpara limitar el resultado de la consulta.

Ejemplo:

SELECT * FROM (
    select row_number() OVER (order by createtime desc) AS ROWINDEX,* 
    from TABLENAME ) TB
WHERE TB.ROWINDEX between 0 and 10

- Con la consulta anterior, obtendré la PÁGINA 1 de los resultados TABLENAME.

Johnson Pham
fuente
2

Necesita crear una tabla virtual mediante el uso WITH table AS, que se menciona en la consulta dada.

Al usar esta tabla virtual, puede realizar la operación CRUD wrt row_number.

CONSULTA:

WITH table AS
-
(SELECT row_number() OVER(ORDER BY UserId) rn, * FROM Users)
-
SELECT * FROM table WHERE UserName='Joe'
-

Puedes usar INSERT, UPDATEo DELETEen la última oración a pesar de SELECT.

Gaurav Chutke
fuente
0

La función SQL Row_Number () es ordenar y asignar un número de orden a las filas de datos en un conjunto de registros relacionados. Por lo tanto, se utiliza para numerar filas, por ejemplo, para identificar las 10 filas principales que tienen la cantidad de orden más alta o identificar la orden de cada cliente que es la cantidad más alta, etc.

Si desea ordenar el conjunto de datos y numerar cada fila separándolos en categorías, usamos Row_Number () con la cláusula Partition By. Por ejemplo, ordenar los pedidos de cada cliente dentro de sí mismo donde el conjunto de datos contiene todos los pedidos, etc.

SELECT
    SalesOrderNumber,
    CustomerId,
    SubTotal,
    ROW_NUMBER() OVER (PARTITION BY CustomerId ORDER BY SubTotal DESC) rn
FROM Sales.SalesOrderHeader

Pero, según tengo entendido, desea calcular el número de filas agrupadas por una columna. Para visualizar el requisito, si desea ver el recuento de todos los pedidos del cliente relacionado como una columna separada además de la información del pedido, puede usar la función de agregación COUNT () con la cláusula Partition By

Por ejemplo,

SELECT
    SalesOrderNumber,
    CustomerId,
    COUNT(*) OVER (PARTITION BY CustomerId) CustomerOrderCount
FROM Sales.SalesOrderHeader
Eralper
fuente
0

Esta consulta:

SELECT ROW_NUMBER() OVER(ORDER BY UserId) From Users WHERE UserName='Joe'

devolverá todas las filas donde UserNameestá A 'Joe'MENOS que no tengaUserName='Joe'

Se enumerarán en orden de UserIDy el row_numbercampo comenzará con 1 e incrementará sin importar cuántas filas contenganUserName='Joe'

Si no funciona para usted, entonces su WHEREcomando tiene un problema O no hay ninguno UserIDen la tabla. Verifique la ortografía de ambos campos UserIDy UserName.

Clark Vera
fuente