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 

カウントを取得します。

2番目の質問では、行の主キーは、特定の行を識別するために何を使用するかです。そのために行番号を使用しないでください。


メインクエリでRow_Number()を返した場合、

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

次に、5行戻したい場合は、現在の行番号を取得し、次のクエリを使用して、currentrow -5の行を特定できます。

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

私の状況では、ユーザーIDが指定されており、特定の数の行であるユーザーIDを取得したいと考えています。行が削除された場合はどうなりますか?その場合、UserId-オフセットに行くことはできません。正しいレコードを取得できないためです。

mytableのselect count(1)を使用してレコード数を選択することをお勧めします。これは非常に迅速で効率的です
Sivajith '20

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. 名前がマットである行番号を取得するには:

    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ように決定する必要がありますか?ありがとう!
ケビンメレディス2017

@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

これにより、クエリにかかる時間が大幅に短縮されます。


あなたが右の全表スキャンについてですが、それはそのために非クラスタ化インデックスを使用することがありますように、それは必ずしもクラスタ化インデックススキャンではないことに注意してください
ヨエルHALB

2
他のRDMBSは、SELECT COUNT最適化したとしても、これは、唯一のSQL-Serverの真実である
ヨエルHALB

7

ROW_NUMBER() 1から始まる各行の一意の番号を返します。これを書くだけで簡単に使用できます。

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

との違いはここRow_number()Rank()ありDense_Rank() ます


7

これを使用して、has句の最初のレコードを取得できます。

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'

すべての行を列挙するに -それ以外の場合は、ユーザー名がJoeである行を列挙するだけであり、これは目標ではありません;-)。
Alex Martelli、

1
@マット:私をペダントと呼んでください。私は「サブ選択」という用語よりも「派生テーブル」または「匿名ビュー」を好む傾向があります。
Mechanical_Meat

1
@adam、私もペダントです-「ネストされた選択」はあなたを幸せにしますか?テーブルやビューなどの用語が使用されていない場合TABLEや、VIEWキーワードがない場合は使用しません... SELECT確かにそうです!-)
Alex Martelli

@アレックス:あなたは有効なポイントを提示します。「ネストされた選択」は私にとってはうまくいきます:)ところで、私はあなたがあなたのコメントと回答に追加した逸話を読んで本当に楽しんでいます。
Mechanical_Meat

@アダム、ありがとう!ここにあるように、私の答えは時々非常に裸のコードですが、時間があるときに私はそれらを肉付けするのが大好きです;-)。
Alex Martelli、

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

(count(*)の代わりに)ROW_NUMBERを絶対に使用したい場合は、いつでも使用できます。

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

-上記のクエリで、からの結果のページ1を取得しTABLENAMEます。


2

WITH table AS特定のクエリで言及されているを使用して仮想テーブルを作成する必要があります。

この仮想テーブルを使用すると、CRUD操作wrtを実行できますrow_number

クエリ:

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

あなたは使用することができINSERTUPDATEまたはDELETE最後の文にもかかわらずでSELECT


0

SQL Row_Number()関数は、関連するレコードセットのデータ行をソートして注文番号を割り当てます。したがって、行に番号を付けるために使用されます。たとえば、注文金額が最も高い上位10行を特定したり、金額が最も高い各顧客の注文を特定したりします。

データセットを並べ替えて、各行をカテゴリに分類することで番号を付けたい場合は、Row_Number()とPartition By句を使用します。たとえば、データセットにすべての注文が含まれる場合、それ自体の中での各顧客の注文の並べ替えなど。

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

しかし、私が理解しているように、列でグループ化された行の数を計算したいとします。要件を視覚化するために、注文情報のほかに、関連する顧客のすべての注文の数を別の列として表示したい場合は、COUNT()集計関数とPartition By句を使用できます。

例えば、

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'

それらはの順にリストされUserIDrow_numberフィールドは1から始まり、インクリメントされますが、多くの行にはUserName='Joe'

それが機能しない場合は、WHEREコマンドに問題があるかUserID、テーブルに何もありません。両方のフィールドのスペルをチェックUserIDしてUserName

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.