sql查询与Row_Number不同

时间:2013-08-08 08:17:38

标签: sql distinct

我正在与sql中的distinct关键字进行斗争。 我只想在列和列中显示唯一(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时尝试了它 然后它无法正常工作。

8 个答案:

答案 0 :(得分:83)

这可以非常简单地完成,你已经非常接近了

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

答案 1 :(得分:43)

使用此:

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 :(得分:20)

This article covers an interesting relationship between ROW_NUMBER() and DENSE_RANK()RANK()函数未被特别处理)。如果您需要在ROW_NUMBER()语句中生成SELECT DISTINCT,则ROW_NUMBER() will produce distinct values before they are removed by the DISTINCT keyword。例如。这个查询

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 |
+---+------------+------+------------+

答案 3 :(得分:3)

使用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

答案 4 :(得分:1)

这样的东西
;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

答案 5 :(得分:0)

试试这个

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

答案 6 :(得分:0)

试试这个:

;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

答案 7 :(得分:0)

问题太老了,我的回答可能不会增加太多,但这是我的两分钱,使查询变得有用:

;WITH DistinctRecords AS (
    SELECT  DISTINCT [col1,col2,col3,..] 
    FROM    tableName 
    where   [my condition]
), 
serialize AS (
   SELECT
    ROW_NUMBER() OVER (PARTITION BY [colNameAsNeeded] ORDER BY  [colNameNeeded]) AS Sr,*
    FROM    DistinctRecords 
)
SELECT * FROM serialize 

使用两个cte的用处在于,您现在可以轻松地在查询中使用序列化记录,并且非常轻松地执行count(*)等。

DistinctRecords将选择所有不同的记录,serialize将序列号应用于不同的记录。病房结束后,您可以将最终的序列化结果用于您的目的,而不会造成混乱。

在大多数情况下可能不需要

Partition By