Sql-запрос, отличный от Row_Number
Я сражаюсь с ключевым словом в 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
.
то он не работает.
Ответы
Ответ 1
Используйте это:
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
Два запроса должны быть эквивалентными.
Технически вы могли
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
будет бесполезным на нем, если вы не связали запрос с некоторые JOIN
s/UNION ALL
...
Ответ 2
Это можно сделать очень просто, вы уже были довольно близки
SELECT distinct id, DENSE_RANK() OVER (ORDER BY id) AS RowNum
FROM table
WHERE fid = 64
Ответ 3
В этой статье рассматриваются интересные отношения между ROW_NUMBER()
и DENSE_RANK()
(функция RANK()
не обрабатывается конкретно). Когда вам понадобится сгенерированный ROW_NUMBER()
в SELECT DISTINCT
, ROW_NUMBER()
будет выдавать различные значения перед их удалением ключевым словом DISTINCT
. Например, этот запрос
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 |
+---+------------+
Обратите внимание, что для предложения ORDER BY
функции DENSE_RANK()
потребуются все остальные столбцы из предложения 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 |
+---+------------+------+------------+
Ответ 4
Использование 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
Ответ 5
Как насчет чего-то вроде
;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
Ответ 6
Попробуйте это
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
Это также возвращает различные идентификаторы
Ответ 7
Попробуйте следующее:
;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