我正在与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
时尝试了它
然后它无法正常工作。
答案 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
您也可以尝试
SELECT distinct id, DENSE_RANK() OVER (ORDER BY id) AS RowNum
FROM @mytable
where fid = 64
答案 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