ROW_NUMBER () nasıl kullanılır?


175

Almak için kullanmak istiyorum ROW_NUMBER()...

  1. Almak için max(ROW_NUMBER())-> Veya sanırım bu da tüm satırların sayısı

Yapmayı denedim:

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

ama işe yaramadı ...

  1. Belirli ROW_NUMBER()bir bilgiyi kullanmak, yani. bir ismim varsa ve ismin hangi satırdan geldiğini bilmek istersem.

# 1 için denediklerime benzer bir şey olacağını varsayıyorum

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

ama bu da işe yaramadı ...

Herhangi bir fikir?

Yanıtlar:


151

İlk soru için, neden sadece kullanmıyorsunuz?

SELECT COUNT(*) FROM myTable 

saymak için.

İkinci soru için, satırın birincil anahtarı, belirli bir satırı tanımlamak için kullanılması gereken şeydir. Bunun için satır numarasını kullanmaya çalışmayın.


Ana sorgunuzda Row_Number () döndürdüyseniz,

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

Sonra 5 satır geri gitmek istediğinizde, geçerli satır numarasını alabilir ve currentrow -5 ile satırı belirlemek için aşağıdaki sorguyu kullanabilirsiniz

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

Benim durumumda bir UserId verildi ve bu belirli sayıda satır geri UserId almak istiyorum. Bir satır silinirse ne olur? Bu durumda, UserId - ofset'e gidemem, çünkü o zaman doğru kaydı alamam.

Kayıt sayısını seçmek için mytable'dan select count (1) kullanmak daha iyidir. Bu çok hızlı ve etkili
Sivajith

46

count()Toplam satır sayısını elde etmek için kullanabileceğiniz başkalarıyla aynı fikirde olmama rağmen , aşağıdakileri nasıl kullanabileceğiniz aşağıda açıklanmıştır row_count():

  1. Toplam satır sayısını elde etmek için:

    with temp as (
        select row_number() over (order by id) as rownum
        from table_name 
    )
    select max(rownum) from temp
  2. Adın Matt olduğu satır numaralarını almak için:

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

Matt için sırasıyla ilk veya son satırı almak için min(rownum)veya tuşunu kullanabilirsiniz max(rownum).

Bunlar çok basit uygulamalardı row_number(). Daha karmaşık gruplama için kullanabilirsiniz. Alt sorgu kullanmadan Gelişmiş gruplama konusundaki yanıtımı kontrol et


Kullanılan sütunun nasıl seçileceğini açıklar order by Xmısınız? Başka bir deyişle, nasıl Xbelirlenmelidir? Teşekkürler!
Kevin Meredith

@KevinMeredith: order by XSatırların atanacağı sırayı belirlemek için kullanacağınız emirdir ROW_NUMBERS(). İlişkisel veritabanlarındaki tabloların adlarına rağmen resmi bir sıralaması olmadığını unutmayın, bu nedenle "1" veya "10" veya "1337" satırını çağırmak istiyorsanız, önce bunları bir ORDER BYcümle kullanarak sipariş etmeniz gerekir. OVER (ORDER BY X)maddeye giren kişidir .
00:25

25

Tablonun toplam satır sayısını döndürmeniz gerekiyorsa, SELECT COUNT(*)ifadeye alternatif bir yol kullanabilirsiniz .

Çünkü SELECT COUNT(*)satır sayısını döndürmek için tam bir tablo taraması yapar, büyük bir tablo için çok uzun zaman alabilir. sysindexesBu durumda sistem tablosunu kullanabilirsiniz . ROWSVeritabanınızdaki her tablo için toplam satır sayısını içeren bir sütun vardır. Aşağıdaki select deyimini kullanabilirsiniz:

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

Bu, sorgunuzun süresini önemli ölçüde azaltır.


Tam tablo taraması hakkında haklısınız, ancak bunun için kümelenmemiş bir dizin kullanabileceği için mutlaka kümelenmiş bir dizin taraması olmadığını unutmayın
yoel halb

2
Diğer RDMBS seçim sayısını optimize ettiği için bu sadece Sql-Server için de geçerlidir
yoel halb

7

ROW_NUMBER() 1 ile başlayan her satır için benzersiz bir sayı döndürür. Bunu şunu yazarak kolayca kullanabilirsiniz:

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

Sen arasındaki farkı bulabilirsiniz Row_number(), Rank()ve Dense_Rank() burada .


7

Bu maddeyi içeren ilk kaydı almak için kullanabilirsiniz

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'

Tüm satırları numaralandırmak için - aksi takdirde sadece kullanıcı adının Joe olduğu satırları numaralandırıyorsunuz; hedef bu değil ;-).
Alex Martelli

1
@Matt: Bana bilgiç deyin; Ben "tür seçim" terimi için "türetilmiş tablo" veya "anonim görünümü" tercih eğilimindedir.
mechanical_meat

1
@adam, ben de bilgiç olduğum için - "iç içe seçim" seni mutlu eder mi? Tablo ya da görünüm gibi terimleri kullanmak istemiyorum ya TABLEda VIEWanahtar kelime yokken ... ama SELECTeminim! -)
Alex Martelli

@Alex: geçerli bir nokta sunuyorsunuz. "İç içe seçme" benim için harika çalışıyor :) Bu arada, yorumlarınıza ve cevaplarınıza eklediğiniz fıkraları okumaktan gerçekten keyif alıyorum.
mechanical_meat

@Adam, teşekkürler! Bazen cevaplarım çok çıplak kod, burada olduğu gibi, ama boş bir dakika ;-) zaman onları ete bayılırım.
Alex Martelli

4

Buradaki soru ile ilgili olmayabilir. Ama kullanırken yararlı olabilir buldum 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

Bunun için kesinlikle ROW_NUMBER kullanmak istiyorsanız (count (*) yerine) her zaman şunu kullanabilirsiniz:

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

2

Row_NumberSınır sorgusu sonucu için kullanabilirsiniz .

Misal:

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

- Yukarıdaki sorgu ile, sonuç PAGE 1 elde edeceğim TABLENAME.


2

WITH table ASVerilen sorguda bahsedilen sanal tablo oluşturmak gerekir .

Bu sanal tabloyu kullanarak CRUD işlemi wrt gerçekleştirebilirsiniz row_number.

SORGU:

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

Sen kullanabilirsiniz INSERT, UPDATEya DELETErağmen son cümlede SELECT.


0

SQL Row_Number () işlevi , ilgili kayıt kümesindeki veri satırlarına sıralamak ve bir sipariş numarası atamaktır. Dolayısıyla, satırları numaralandırmak için kullanılır, örneğin en yüksek sipariş miktarına sahip ilk 10 satırı veya her müşterinin en yüksek tutar olan sırasını tanımlamak vb.

Veri kümesini ve numarayı her bir satırı kategorilere ayırarak sıralamak isterseniz, Partition By yan tümcesiyle Row_Number () öğesini kullanırız. Örneğin, veri kümesinin tüm siparişleri içerdiği her bir müşterinin siparişlerini sıralama.

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

Ancak anladığım kadarıyla, bir sütuna göre gruplandırılmış satır sayısını hesaplamak istiyorsunuz. Gereksinimi görselleştirmek için, ilgili müşterinin tüm siparişlerinin sipariş bilgilerinin yanı sıra ayrı bir sütun olarak sayılmasını istiyorsanız, Partition By deyimiyle COUNT () toplama işlevini kullanabilirsiniz

Örneğin,

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

0

Bu sorgu:

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

nerede tüm satırlar dönecektir UserNameolduğunu 'Joe'hiçbir var SÜRECEUserName='Joe'

Bunlar sırayla listelenir UserIDve row_numberalan 1 ile başlar ve artar ancak birçok satırdaUserName='Joe'

Sizin için işe yaramazsa, WHEREkomutunuzda bir sorun var VEYA UserIDtabloda yok. Her iki alan için de yazım denetimi yapın UserIDve UserName.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.