web-dev-qa-db-ja.com

Row_Numberと異なるSQLクエリ

sqlの個別のキーワードと戦っています。私はちょうど列に一意の(distinct)値のすべての行番号を表示したいので、試しました:

SELECT distinct id, ROW_NUMBER() OVER (ORDER BY  id) AS RowNum
                             FROM table
                             where fid = 64

ただし、次のコードはdistinct値を提供します。

SELECT distinct id FROM table where fid = 64

しかし、Row_Numberで試してみました。
それは動作していません。

47

これを使って:

SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS RowNum FROM
    (SELECT DISTINCT id FROM table WHERE fid = 64) Base

クエリの「出力」を別の「入力」として配置します。

CTEの使用:

; WITH Base AS (
    SELECT DISTINCT id FROM table WHERE fid = 64
)

SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS RowNum FROM Base

2つのクエリは同等である必要があります。

技術的にはできます

SELECT DISTINCT id, ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) AS RowNum 
    FROM table
    WHERE fid = 64

しかし、DISTINCTフィールドの数を増やす場合は、これらのすべてのフィールドをPARTITION BYに入れる必要があります。たとえば、

SELECT DISTINCT id, description,
    ROW_NUMBER() OVER (PARTITION BY id, description ORDER BY id) AS RowNum 
    FROM table
    WHERE fid = 64

ここで標準の命名規則に違反していることを理解することを願っています、idはおそらくプライマリキーであるため、定義上一意であるため、クエリをDISTINCTs/UNION ALLと結合しない限り、JOINは使用できません。

44
xanatos

これは非常に簡単に行うことができます、あなたはすでにかなり近くにいました

SELECT distinct id, DENSE_RANK() OVER (ORDER BY  id) AS RowNum
FROM table
WHERE fid = 64
85
t-clausen.dk

この記事では、ROW_NUMBER()DENSE_RANK()の興味深い関係について説明していますRANK()関数は特に扱われていません)。 SELECT DISTINCTステートメントでROW_NUMBER()を生成する必要がある場合、 ROW_NUMBER()は個別の値beforeDISTINCTキーワードによって削除されます 。例えば。このクエリ

SELECT DISTINCT
  v, 
  ROW_NUMBER() OVER (ORDER BY v) row_number
FROM t
ORDER BY v, row_number

...この結果が生成される場合があります(DISTINCTは効果がありません):

+---+------------+
| V | ROW_NUMBER |
+---+------------+
| a |          1 |
| a |          2 |
| a |          3 |
| b |          4 |
| c |          5 |
| c |          6 |
| d |          7 |
| e |          8 |
+---+------------+

一方、このクエリ:

SELECT DISTINCT
  v, 
  DENSE_RANK() OVER (ORDER BY v) row_number
FROM t
ORDER BY v, row_number

...この場合、おそらく必要なものが生成されます。

+---+------------+
| V | ROW_NUMBER |
+---+------------+
| a |          1 |
| b |          2 |
| c |          3 |
| d |          4 |
| e |          5 |
+---+------------+

DENSE_RANK()関数のORDER BY句が正しく機能するためには、SELECT DISTINCT句の他のすべての列が必要になることに注意してください。

比較する3つの機能すべて

PostgreSQL/Sybase/SQL標準構文(WINDOW句)の使用:

SELECT
  v,
  ROW_NUMBER() OVER (window) row_number,
  RANK()       OVER (window) rank,
  DENSE_RANK() OVER (window) dense_rank
FROM t
WINDOW window AS (ORDER BY v)
ORDER BY v

...次のものが得られます:

+---+------------+------+------------+
| V | ROW_NUMBER | RANK | DENSE_RANK |
+---+------------+------+------------+
| a |          1 |    1 |          1 |
| a |          2 |    1 |          1 |
| a |          3 |    1 |          1 |
| b |          4 |    4 |          2 |
| c |          5 |    5 |          3 |
| c |          6 |    5 |          3 |
| d |          7 |    7 |          4 |
| e |          8 |    8 |          5 |
+---+------------+------+------------+
21
Lukas Eder

DISTINCTを使用すると、フィールドを追加するときに問題が発生し、選択の問題を隠すこともできます。次のような代替としてGROUP BYを使用します。

SELECT id
      ,ROW_NUMBER() OVER (ORDER BY  id) AS RowNum
  FROM table
 where fid = 64
 group by id

次に、選択から他の興味深い情報を次のように追加できます。

,count(*) as thecount

または

,max(description) as description
3
Michael Potter

のようなものはどうですか

;WITH DistinctVals AS (
        SELECT  distinct id 
        FROM    table 
        where   fid = 64
    )
SELECT  id,
        ROW_NUMBER() OVER (ORDER BY  id) AS RowNum
FROM    DistinctVals

SQL Fiddle DEMO

また試すことができます

SELECT distinct id, DENSE_RANK() OVER (ORDER BY  id) AS RowNum
FROM @mytable
where fid = 64

SQL Fiddle DEMO

1
Adriaan Stander

これを試して

SELECT distinct id
FROM  (SELECT id, ROW_NUMBER() OVER (ORDER BY  id) AS RowNum
      FROM table
      WHERE fid = 64) t

または、行番号の代わりにRANK()を使用し、レコードを選択しますDISTINCT rank

SELECT id
FROM  (SELECT id, ROW_NUMBER() OVER (PARTITION BY  id ORDER BY  id) AS RowNum
      FROM table
      WHERE fid = 64) t
WHERE t.RowNum=1

これは、個別のIDも返します

0
Nithesh

これを試して:

;WITH CTE AS (
               SELECT DISTINCT id FROM table WHERE fid = 64
             )
SELECT id, ROW_NUMBER() OVER (ORDER BY  id) AS RowNum
  FROM cte
 WHERE fid = 64
0
hims056