Як використовувати ROW_NUMBER ()?


175

Я хочу використовувати ROW_NUMBER() щоб отримати ...

  1. Щоб отримати max(ROW_NUMBER()) -> Або я здогадуюсь, що це також буде підрахунок усіх рядків

Я намагався робити:

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

але, здавалося, не вийшло ...

  1. Отримати ROW_NUMBER() використання даної інформації, тобто. якщо у мене є ім’я, і я хочу знати, з якого рядка походить назва.

Я припускаю, що це буде щось подібне до того, що я спробував для №1

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

але це також не вийшло ...

Будь-які ідеї?

Відповіді:


150

Для першого питання, чому б не просто використовувати?

SELECT COUNT(*) FROM myTable 

щоб отримати рахунок.

А для другого питання первинним ключем рядка є те, що слід використовувати для ідентифікації конкретного рядка. Не намагайтеся використовувати для цього номер рядка


Якщо ви повернули Row_Number () у своєму головному запиті,

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

Тоді, коли ви хочете піти на 5 рядків назад, тоді ви можете взяти номер поточного рядка і скористатися наступним запитом, щоб визначити рядок з поточним числом -5

SELECT us.Id
FROM (SELECT ROW_NUMBER() OVER (ORDER BY id) AS Row, Id
     FROM User ) us 
WHERE Row = CurrentRow - 5   

У моїй ситуації мені надається UserId, і я хочу повернути UserId, який містить певну кількість рядків. Що робити, якщо рядок буде видалено? У такому випадку я не можу просто змінити UserId - зміщення, тому що тоді я не отримав би правильний запис.

Для вибору кількості записів краще використовувати select count (1) з mytable. Це так швидко і ефективно
Сіваїт

46

Хоча я згоден з іншими, якими ти міг би скористатися count() для отримання загальної кількості рядків, ось як ви можете використовувати row_count():

  1. Щоб отримати загальну кількість рядків:

    with temp as (
        select row_number() over (order by id) as rownum
        from table_name 
    )
    select max(rownum) from temp
  2. Щоб отримати номери рядків, де ім'я 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'

Можна додатково використовувати min(rownum) або max(rownum)отримати перший або останній ряд для Метта відповідно.

Це були дуже прості реалізації row_number(). Ви можете використовувати його для більш складного групування. Перевірте мою відповідь на розширене групування, не використовуючи підзапит


Чи можете ви поясніть, як вибрати стовпець, в якому використовується order by X? Іншими словами, як слід Xвизначитись? Дякую!
Кевін Мередіт

@KevinMeredith: order by Xце порядок, який ви будете використовувати для визначення порядку, в якому будуть призначені рядки ROW_NUMBERS(). Пам'ятайте, що таблиці в реляційних базах даних, незважаючи на їх назву, не мають формального впорядкування, тому, якщо ви хочете викликати рядок "1" або "10" або "1337", вам потрібно спочатку замовити їх за допомогою ORDER BYпункту, який той, що йде в OVER (ORDER BY X)пункті.
Wtrmute

25

Якщо вам потрібно повернути загальну кількість рядків таблиці, ви можете скористатися альтернативним способом для SELECT COUNT(*)оператора.

Оскільки SELECT COUNT(*)робить повне сканування таблиці, щоб повернути кількість рядків, для великої таблиці може знадобитися дуже багато часу. sysindexesЗамість цього ви можете використовувати системну таблицю. Є ROWSстовпець, який містить загальну кількість рядків для кожної таблиці вашої бази даних. Ви можете використовувати наступний оператор select:

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

Це різко скоротить час, який потребує ваш запит.


Ви маєте рацію щодо повного сканування таблиці, але зауважте, що це не обов'язково кластерне сканування індексів, оскільки воно може використовувати для цього
некластеризований

2
Також це справедливо лише для Sql-Server, оскільки інші RDMBS оптимізували кількість вибору
yoel halb

7

ROW_NUMBER() повертає унікальне число для кожного рядка, починаючи з 1. Ви можете легко використовувати це, просто записавши:

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

Ви можете знайти різницю між Row_number(), Rank()і Dense_Rank() тут .


7

Ви можете використовувати це для отримання першого запису, де є пункт

SELECT TOP(1) * , ROW_NUMBER() OVER(ORDER BY UserId) AS rownum 
FROM     Users 
WHERE    UserName = 'Joe'
ORDER BY rownum ASC

4
SELECT num, UserName FROM 
 (SELECT UserName, ROW_NUMBER() OVER(ORDER BY UserId) AS num
  From Users) AS numbered
WHERE UserName='Joe'

Для перерахування всіх рядків - інакше ви просто перераховуєте рядки, де ім'я користувача - Джо, що не є ціллю ;-).
Алекс Мартеллі

1
@Matt: Називай мене педантом; Я, як правило, віддаю перевагу або "похідній таблиці", або "анонімному виду", ніж термін "підбір".
Mechan_meat

1
@adam, оскільки я теж педант - чи "вкладений вибір" зробить вас щасливішими? Я не люблю з умовами використання , такі як таблиці або подання , коли немає TABLEабо VIEWключове слово не навколо ... але SELECTвпевнений , що це -!)
Алекс Мартеллі

@ Алекс: ви представляєте дійсну точку. "Вкладений вибір" для мене чудово працює :) До речі, мені дуже подобається читати анекдоти, які ви додаєте до своїх коментарів та відповідей.
механічний_міс

@Adam, дякую! Іноді мої відповіді є дуже голими кодами, як тут, але я люблю їх розміщувати, коли у мене є вільна хвилина ;-).
Алекс Мартеллі

4

Тут не може бути пов'язано з питанням. Але я виявив, що це може бути корисно при використанні ROW_NUMBER-

SELECT *,
ROW_NUMBER() OVER (ORDER BY (SELECT 100)) AS Any_ID 
FROM #Any_Table

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

2

Якщо ви абсолютно хочете використовувати для цього ROW_NUMBER (замість count (*)), ви завжди можете використовувати:

SELECT TOP 1 ROW_NUMBER() OVER (ORDER BY Id)   
FROM USERS  
ORDER BY ROW_NUMBER() OVER (ORDER BY Id) DESC

2

Ви можете використовувати Row_Numberдля обмеження результату запиту.

Приклад:

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

- З вищезазначеним запитом я отримаю PAGE 1 результатів TABLENAME.


2

Потрібно створити віртуальну таблицю за допомогою WITH table AS, що згадується в даному Запиті.

За допомогою цієї віртуальної таблиці ви можете виконати операцію CRUD row_number.

ПИТАННЯ:

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

Ви можете використовувати INSERT, UPDATEабо DELETEв останньому реченні по всупереч SELECT.


0

Функція SQL Row_Number () полягає в сортуванні та присвоєнні номера замовлення рядкам даних у відповідному наборі записів. Тож він використовується для нумерації рядків, наприклад, для визначення топ-10 рядків, які мають найвищу суму замовлення, або визначення порядку кожного клієнта, який є найбільшою сумою тощо.

Якщо ви хочете сортувати набір даних та нумерувати кожен рядок, відокремлюючи їх у категорії, ми використовуємо Row_Number () з підрозділом розділення. Наприклад, сортування замовлень кожного клієнта всередині себе, де набір даних містить усі замовлення тощо.

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

Але, як я розумію, ви хочете обчислити кількість рядків, згрупованих за стовпцем. Щоб візуалізувати вимогу, якщо ви хочете бачити кількість всіх замовлень пов'язаного клієнта як окремий стовпець, окрім інформації про замовлення, ви можете використовувати функцію агрегації COUNT () за допомогою розділу розділення

Наприклад,

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

0

Цей запит:

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

поверне всі рядки там, де UserNameце 'Joe'БЕЗПЕЧНО, у вас немаєUserName='Joe'

Вони будуть перераховані в порядку, UserIDі row_numberполе розпочнеться з 1 і приростом, проте багато рядків містятьUserName='Joe'

Якщо це не працює для вас, у вашої WHEREкоманди є проблема АБО немає UserIDв таблиці. Перевірте правопис обох полів UserIDта UserName.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.