Bagaimana cara saya menggunakan ROW_NUMBER ()?


175

Saya ingin menggunakan ROW_NUMBER()untuk ...

  1. Untuk mendapatkan max(ROW_NUMBER())-> Atau saya kira ini juga akan menjadi hitungan semua baris

Saya mencoba melakukan:

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

tapi sepertinya itu tidak berhasil ...

  1. Untuk ROW_NUMBER()menggunakan sepotong informasi yang diberikan, yaitu. jika saya memiliki nama dan saya ingin tahu dari baris mana nama itu berasal.

Saya menganggap itu akan menjadi sesuatu yang mirip dengan apa yang saya coba untuk # 1

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

tapi ini tidak berhasil ...

Ada Ide?

Jawaban:


150

Untuk pertanyaan pertama, mengapa tidak digunakan saja?

SELECT COUNT(*) FROM myTable 

untuk mendapatkan hitungan.

Dan untuk pertanyaan kedua, kunci utama dari baris adalah apa yang harus digunakan untuk mengidentifikasi baris tertentu. Jangan coba dan gunakan nomor baris untuk itu.


Jika Anda mengembalikan Row_Number () dalam permintaan utama Anda,

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

Kemudian ketika Anda ingin pergi 5 baris kembali maka Anda dapat mengambil nomor baris saat ini dan menggunakan permintaan berikut untuk menentukan baris dengan arus -5

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

Dalam situasi saya, saya diberi UserId, dan saya ingin mendapatkan UserId itu sejumlah baris kembali. Bagaimana jika satu baris terhapus? Dalam hal ini, saya tidak bisa hanya pergi UserId - offset, karena saya tidak akan mendapatkan catatan yang benar.

Lebih baik menggunakan count pilih (1) dari mytable untuk memilih jumlah record. Ini sangat cepat dan efisien
Sivajith

46

Meskipun saya setuju dengan orang lain yang dapat Anda gunakan count()untuk mendapatkan jumlah total baris, berikut adalah bagaimana Anda dapat menggunakan row_count():

  1. Untuk mendapatkan jumlah total baris:

    with temp as (
        select row_number() over (order by id) as rownum
        from table_name 
    )
    select max(rownum) from temp
  2. Untuk mendapatkan nomor baris dengan nama 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'

Anda selanjutnya dapat menggunakan min(rownum)atau max(rownum)untuk mendapatkan baris pertama atau terakhir untuk Matt.

Ini adalah implementasi yang sangat sederhana row_number(). Anda dapat menggunakannya untuk pengelompokan yang lebih kompleks. Lihat respons saya tentang pengelompokan Tingkat Lanjut tanpa menggunakan sub kueri


Bisakah Anda jelaskan bagaimana memilih kolom yang digunakan order by X? Dengan kata lain, bagaimana harus Xditentukan? Terima kasih!
Kevin Meredith

@KevinMeredith: Ini order by Xadalah urutan yang akan Anda gunakan untuk menentukan urutan penempatan baris ROW_NUMBERS(). Ingatlah bahwa tabel dalam database relasional, terlepas dari namanya, tidak memiliki pemesanan formal, jadi jika Anda ingin memanggil baris "1" atau "10" atau "1337", Anda perlu memesannya terlebih dahulu menggunakan ORDER BYklausa, yang adalah salah satu yang masuk dalam OVER (ORDER BY X)klausa.
Wtrmute

25

Jika Anda perlu mengembalikan jumlah baris total tabel, Anda bisa menggunakan cara alternatif untuk SELECT COUNT(*)pernyataan tersebut.

Karena SELECT COUNT(*)membuat pemindaian tabel penuh untuk mengembalikan jumlah baris, bisa sangat lama untuk tabel besar. Anda bisa menggunakan sysindexestabel sistem sebagai gantinya dalam hal ini. Ada ROWSkolom yang berisi jumlah baris total untuk setiap tabel di database Anda. Anda dapat menggunakan pernyataan pilih berikut:

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

Ini secara drastis akan mengurangi waktu yang dibutuhkan kueri Anda.


Anda benar tentang pemindaian tabel penuh, tetapi perhatikan bahwa itu tidak selalu merupakan pemindaian indeks berkerumun, karena mungkin menggunakan indeks non-berkerumun untuk itu
yoel halb

2
Juga ini hanya berlaku untuk Sql-Server, karena RDMBS lain telah mengoptimalkan jumlah yang dipilih
yoel halb

7

ROW_NUMBER() mengembalikan nomor unik untuk setiap baris dimulai dengan 1. Anda dapat dengan mudah menggunakan ini hanya dengan menulis:

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

Anda dapat menemukan perbedaan antara Row_number(), Rank()dan di Dense_Rank() sini .


7

Anda dapat menggunakan ini untuk mendapatkan catatan pertama yang memiliki klausa

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'

Untuk menghitung semua baris - jika tidak, Anda hanya menghitung baris di mana nama pengguna adalah Joe, yang bukan tujuannya ;-).
Alex Martelli

1
@ Matt: Panggil aku pedant; Saya cenderung memilih "tabel turunan" atau "tampilan anonim" daripada istilah "sub pilih".
mechanical_meat

1
@adam, karena saya pedant juga - akan "bersarang pilih" membuat Anda lebih bahagia? Saya tidak suka dengan penggunaan istilah seperti tabel atau view ketika tidak ada TABLEatau VIEWkata kunci adalah sekitar ... tapi SELECTpasti adalah -!)
Alex Martelli

@Alex: Anda menyajikan poin yang valid. "Nested select" berfungsi baik untuk saya :) Omong-omong, saya sangat menikmati membaca anekdot yang Anda tambahkan ke komentar dan jawaban Anda.
mechanical_meat

@ Adam, terima kasih! Kadang-kadang jawaban saya adalah kode yang sangat telanjang, seperti di sini, tetapi saya sangat suka menyempurnakannya ketika saya memiliki waktu luang ;-).
Alex Martelli

4

Mungkin tidak terkait dengan pertanyaan di sini. Tapi saya menemukan itu bisa bermanfaat saat menggunakan 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

Jika Anda benar-benar ingin menggunakan ROW_NUMBER untuk ini (alih-alih menghitung (*)) Anda selalu dapat menggunakan:

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

2

Anda dapat menggunakan Row_Numberuntuk hasil kueri batas.

Contoh:

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

- Dengan kueri di atas, saya akan mendapatkan PAGE 1 hasil dari TABLENAME.


2

Perlu membuat tabel virtual dengan menggunakan WITH table AS, yang disebutkan dalam Kueri yang diberikan.

Dengan menggunakan tabel virtual ini, Anda dapat melakukan operasi CRUD row_number.

PERTANYAAN:

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

Anda dapat menggunakan INSERT, UPDATEatau DELETEdalam kalimat terakhir meskipun SELECT.


0

Fungsi SQL Row_Number () adalah untuk mengurutkan dan menetapkan nomor pesanan ke baris data dalam kumpulan catatan terkait. Jadi digunakan untuk memberi nomor baris, misalnya untuk mengidentifikasi 10 baris teratas yang memiliki jumlah pesanan tertinggi atau mengidentifikasi urutan setiap pelanggan yang merupakan jumlah tertinggi, dll.

Jika Anda ingin mengurutkan dataset dan memberi nomor setiap baris dengan memisahkannya ke dalam kategori, kami menggunakan Row_Number () dengan klausa Partition By. Misalnya, menyortir pesanan dari setiap pelanggan di dalam dirinya sendiri di mana dataset berisi semua pesanan, dll.

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

Tapi seperti yang saya mengerti Anda ingin menghitung jumlah baris yang dikelompokkan berdasarkan kolom. Untuk memvisualisasikan persyaratan, jika Anda ingin melihat jumlah semua pesanan pelanggan terkait sebagai kolom terpisah di samping info pesanan, Anda dapat menggunakan fungsi agregasi COUNT () dengan Partition By clause

Sebagai contoh,

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

0

Kueri ini:

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

akan mengembalikan semua baris mana UserNameadalah 'Joe'KECUALI Anda tidak memilikiUserName='Joe'

Mereka akan terdaftar dalam urutan UserIDdan row_numberbidang akan mulai dengan 1 dan kenaikan berapa pun banyak baris mengandungUserName='Joe'

Jika tidak bekerja untuk Anda maka WHEREperintah Anda memiliki masalah ATAU tidak ada UserIDdalam tabel. Periksa ejaan untuk kedua bidang UserIDdan UserName.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.