Подтвердить что ты не робот

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.
то он не работает.

4b9b3361

Ответ 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

SQL Fiddle DEMO

Вы также можете попробовать

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

SQL Fiddle DEMO

Ответ 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