在下面的查询中,当
DENSE_RANK() OVER (ORDER BY m_id)
中的列是主表列之一时,我得到了我想要的结果。类似的东西
m_id | m_txt | s_txt | s_日期 | 系统排名 |
---|---|---|---|---|
1 | 第 1 项 | 空 | 空 | 1 |
2 | 第 2 项 | 子项2-3 | 2020年1月1日 | 2 |
2 | 第 2 项 | 子项2-2 | 2025 年 10 月 11 日 | 2 |
2 | 第 2 项 | 子项2-1 | 2023 年 7 月 1 日 | 2 |
3 | 第 3 项 | 空 | 空 | 3 |
4 | 第 4 项 | 子项4-3 | 2020年3月1日 | 4 |
4 | 第 4 项 | 子项4-2 | 2020年5月1日 | 4 |
4 | 第 4 项 | 子项4-1 | 2026 年 3 月 1 日 | 4 |
这就是我想要的,因为我想按 m_id 进行[密集]排名。最终,我会选择前10名或者21到30之间的排名来获得10件物品。 DESC 同样适用。
但是,如果我尝试从查找表中按
s_date
或 s_date desc
排序,这就是我遇到问题的时候。
问题 - 是否有可能得到这样的结果(如下)?在这里,我真的很关心同一 ID 下的项目被一个接一个地列出,并且在每个这样的组中,最重要的日期首先列出。?我已经无法思考,我怎样才能达到这个结果。谢谢
m_id | m_txt | s_txt | s_日期 | 系统排名 |
---|---|---|---|---|
4 | 第 4 项 | 子项4-1 | 2026 年 3 月 1 日 | 1 |
4 | 第 4 项 | 子项4-2 | 2020年5月1日 | 1 |
4 | 第 4 项 | 子项4-3 | 2020年3月1日 | 1 |
2 | 第 2 项 | 子项2-2 | 2025 年 10 月 11 日 | 2 |
2 | 第 2 项 | 子项2-1 | 2023 年 7 月 1 日 | 2 |
2 | 第 2 项 | 子项2-3 | 2020年1月1日 | 2 |
1 | 第 1 项 | 空 | 空 | 3 |
3 | 第 3 项 | 空 | 空 | 4 |
SELECT
Outer_Tbl_Alias.*,
sys___max_rank AS sys___countAllFoundRecords
FROM
(
SELECT Rank_tbl_Alias.*,
MAX(sys___rank) OVER() AS sys___max_rank
FROM
(
SELECT
Union_Tbl_Alias.*,
DENSE_RANK() OVER (ORDER BY m_id) AS sys___rank
FROM
(
SELECT
PerfData1.id m_id,
PerfData1.c1 m_txt,
PerfData2.c1 s_txt,
PerfData2.d s_date
FROM
PerfData1 left Join
PerfData2 On PerfData1.id = PerfData2.fkid
WHERE (1 = 1) AND
PerfData1.id < 200
UNION
SELECT
PerfData3.id m_id,
PerfData3.c1 m_txt,
PerfData4.c1 s_txt,
PerfData4.d s_date
FROM
PerfData3 left Join
PerfData4 On PerfData3.id = PerfData4.fkid
WHERE (1 = 1) AND
PerfData3.id > 800
) Union_Tbl_Alias
ORDER BY
m_id
OFFSET 0 ROWS
FETCH NEXT 950 ROWS ONLY ) Rank_tbl_Alias
) Outer_Tbl_Alias
-- generate structure
create table PerfData1 (id int primary key, c1 varchar(100));
create table PerfData2 (id int identity primary key, fkId int, c1 varchar(100), d datetime, FOREIGN KEY (fkId) REFERENCES PerfData1(id));
create table PerfData3 (id int primary key, c1 varchar(100));
create table PerfData4 (id int identity primary key, fkId int, c1 varchar(100), d datetime, FOREIGN KEY (fkId) REFERENCES PerfData3(id));
-- generate data
DECLARE @id INTEGER = 0, @date datetime = GetDate();
begin
WHILE @id <= 10000
BEGIN
SET @id = @id + 1;
insert into PerfData1 (id, c1) values (@id, concat( 'item ', @id) );
if @id % 2 = 0
begin
SET @date = DateAdd(minute, abs(rand() * 10000), GetDate());
insert into PerfData2 (fkId, c1, d) values (@id, concat( 'SubItem ', @id, '-', 1), @date);
SET @date = DateAdd(minute, abs(rand() * 100000), GetDate());
insert into PerfData2 (fkId, c1, d) values (@id, concat( 'SubItem ', @id, '-', 2), @date);
SET @date = DateAdd(minute, abs(rand() * 200000), GetDate());
insert into .PerfData2 (fkId, c1, d) values (@id, concat( 'SubItem ', @id, '-', 3), @date);
end;
END;
end;
你可以这样做:
with
q as (
select * from t
),
r as (
select x.*, row_number() over(order by md desc, sys_rank) as new_rank
from (
select sys_rank, max(s_date) as md from q group by sys_rank
) x
)
select q.*, r.new_rank
from q
join r on r.sys_rank = q.sys_rank
order by r.new_rank, q.s_date desc
结果:
m_id m_txt s_txt s_date sys_rank new_rank
----- ------- ------------ ----------- --------- --------
4 item 4 SubItem 4-1 2026-03-01 4 1
4 item 4 SubItem 4-2 2020-05-01 4 1
4 item 4 SubItem 4-3 2020-03-01 4 1
2 item 2 SubItem 2-2 2025-10-11 2 2
2 item 2 SubItem 2-1 2023-07-01 2 2
2 item 2 SubItem 2-3 2020-01-01 2 2
1 item 1 null null 1 3
3 item 3 null null 3 4
请参阅 db<>fiddle 处的运行示例。