我有三个表格和列,如下所示
resource: id, location.
subject: id, name
resource_subject: resource_id, subject_id
"资源"之间的关系和"主题"是多对多的。这是我的查询:
select r.* from resource r
inner join resource_subject subject on r.id = subject.resource_id
where (subject.subject_id= 2 or subject.subject_id= 4)
如上所述查询可能会产生重复记录,因为一个资源可能属于多个主题。因此,要删除重复项,我使用 distinct ,如下所示:
select distinct r.* from resource r
inner join resource_subject subject on r.id = subject.resource_id
where (subject.subject_id= 2 or subject.subject_id= 4)
现在我想对独特记录进行分页。我读了这篇SO帖子,
What is the best way to paginate results in SQL Server
我对使用 ROW_NUMBER()感兴趣。但是,使用ROW_NUMBER()会使重复记录唯一:
select distinct ROW_NUMBER() over( order by r.id asc) AS rownum, r.* from resource r
inner join resource_subject subject on r.id = subject.resource_id
where (subject.subject_id= 2 or subject.subject_id= 4)
如何在#34; distinct"之后对记录执行ROW_NUMBER()?
答案 0 :(得分:2)
DENSE_RANK()
代替 ROW_NUMBER()
is to SELECT
what DENSE_RANK()
is to SELECT DISTINCT
。 DENSE_RANK()
的以下应用程序将生成行号,就好像它们在应用DISTINCT
后生成一样。
select distinct DENSE_RANK() over( order by r.id asc) AS rownum, r.* from resource r
inner join resource_subject subject on r.id = subject.resource_id
where (subject.subject_id= 2 or subject.subject_id= 4)
最好通过示例解释,也可以从linked article
解释SELECT
v,
ROW_NUMBER() OVER(ORDER BY v),
RANK() OVER(ORDER BY v),
DENSE_RANK() OVER(ORDER BY v)
FROM (
VALUES('a'),('a'),('a'),('b'),
('c'),('c'),('d'),('e')
) t(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 |
答案 1 :(得分:1)
在外部查询中生成row_number
;WITH cte
AS (SELECT Row_number()OVER( ORDER BY id ASC) AS rownum,
*
FROM (SELECT DISTINCT r.*
FROM resource r
INNER JOIN resource_subject subject
ON r.id = subject.resource_id
WHERE subject.subject_id IN ( 2, 4 )) A)
SELECT *
FROM cte
WHERE rownum >= 1
AND rownum <= 10
但如果您使用的是Sql Server 2012+
,请使用OFFSET
进行分页,这将比Row_number
快
SELECT DISTINCT r.*
FROM resource r
INNER JOIN resource_subject subject
ON r.id = subject.resource_id
WHERE subject.subject_id IN ( 2, 4 )
ORDER BY r.id
offset 1 rows FETCH next 10 rows only;