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
で試してみました。
それは動作していません。
これを使って:
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
はおそらくプライマリキーであるため、定義上一意であるため、クエリをDISTINCT
s/UNION ALL
と結合しない限り、JOIN
は使用できません。
これは非常に簡単に行うことができます、あなたはすでにかなり近くにいました
SELECT distinct id, DENSE_RANK() OVER (ORDER BY id) AS RowNum
FROM table
WHERE fid = 64
この記事では、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
句の他のすべての列が必要になることに注意してください。
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 |
+---+------------+------+------------+
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
のようなものはどうですか
;WITH DistinctVals AS (
SELECT distinct id
FROM table
where fid = 64
)
SELECT id,
ROW_NUMBER() OVER (ORDER BY id) AS RowNum
FROM DistinctVals
また試すことができます
SELECT distinct id, DENSE_RANK() OVER (ORDER BY id) AS RowNum
FROM @mytable
where fid = 64
これを試して
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も返します
これを試して:
;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