我想选择前n个组的记录。我的数据如下:
表'跑步者':
id gid status rtime
---------------------------
100 5550 1 2016-08-19
200 5550 2 2016-08-22
300 5550 1 2016-08-30
100 6050 3 2016-09-01
200 6050 1 2016-09-02
100 6250 1 2016-09-11
200 6250 1 2016-09-15
300 6250 3 2016-09-19
表'静态'
id description env
-------------------------------
100 something 1 somewhere 1
200 something 2 somewhere 2
300 something 3 somewhere 3
单元ID(id)在组内是唯一的,但在其列中不唯一,因为该组的实例是定期生成的。组ID(gid)分配给每个单元,但不会在多个实例上生成。
现在,组合表并选择所有内容或按特定值过滤很容易,但如何在不直接引用组ID的情况下选择前两组的所有记录? 预期结果将是:
id gid description status rtime
--------------------------------------
300 6250 something 2 3 2016-09-19
200 6250 something 1 1 2016-09-15
100 6250 something 3 1 2016-09-11
200 6050 something 2 1 2016-09-02
100 6050 something 1 3 2016-09-01
额外问题:当我过滤这样的时间范围时:
[...]
WHERE runner.rtime BETWEEN '2016-08-25' AND '2016-09-16'
是否有一种简单的方法可以确保群组不被切断,但是要么显示所有记录,要么根本不显示?
答案 0 :(得分:1)
嗯。我怀疑这可能会做你想要的:
select top (1) with ties r.*
from runner r
order by min(rtime) over (partition by gid), gid;
至少,这将获得完整的第一组。
无论如何,我们的想法是将gid
作为order by
中的关键字并使用top with ties
。
答案 1 :(得分:1)
您可以使用ROW_NUMBER()
执行此操作。首先,创建一个对组进行排名的查询:
SELECT gid, ROW_NUMBER() over (order by gid desc) as RN
FROM Runner
GROUP BY gid
然后将其用作派生表以获取其他信息,并使用where子句过滤到要查看的组数。例如,下面将返回前5个组RN <= 5
:
SELECT id, R.gid, description, status, rtime
FROM (SELECT gid, ROW_NUMBER() over (order by gid desc) as RN
FROM Runner
GROUP BY gid) G
INNER JOIN Runner R on R.gid = G.gid
INNER JOIN Statis S on S.id = R.id
WHERE RN <= 5 --Change this to see more or less groups
关于日期的第二个问题,您可以使用如下子查询来执行此操作:
SELECT *
FROM Runner
WHERE gid IN (SELECT gid
FROM Runner
WHERE rtime BETWEEN '2016-08-25' AND '2016-09-16')
答案 2 :(得分:1)
您可以执行以下操作
with report as(
select n.id,n.gid,m.description,n.status,n.rtime, dense_rank() over(order by gid desc) as RowNum
from @table1 n
inner join @table2 m on n.id = m.id )
select id,gid,description,status,rtime
from report
where RowNum<=2 -- <-- here n=2
order by gid desc,rtime desc
这是一个有效的demo
答案 3 :(得分:1)
DENSE_RANK
看起来像是一个理想的解决方案
Select * From
(
select DENSE_RANK() over (order by gid desc) as D_RN, r.*
from runner r
) A
Where D_RN = 1
答案 4 :(得分:0)
无需使用排名功能(ROW_NUMBER
,DENSE_RANK
等)。
SELECT r.id, gid, [description], [status], rtime
FROM runner r
INNER JOIN static s ON r.id = s.id
WHERE gid IN (
SELECT TOP 2 gid FROM runner GROUP BY gid ORDER BY gid DESC
)
ORDER BY rtime DESC;
同样使用CTE:
WITH grouped
AS
(
SELECT TOP 2 gid
FROM runner GROUP BY gid ORDER BY gid DESC
)
SELECT r.id, grouped.gid, [description], [status], rtime
FROM runner r
INNER JOIN static s ON r.id = s.id
INNER JOIN grouped ON r.gid = grouped.gid
ORDER BY rtime DESC;