假设我有一个返回以下数据的查询:
id date
-- ------
1 2015-01-12
1 ... // here I might have X more rows
1 2015-06-30
2 2015-01-12
2 ... // here I might have Y more rows
2 2015-05-20
...
鉴于X, Y >= 120 and X != Y
和查询的顺序是id, date ASC
,我想要一种方法来检索id 1的记录号120和id 2的120(对于每个不同的ID,依此类推) ),类似于:
id date
-- --------
1 2015-03-24 // this is the record 120 for id = 1
2 2015-04-26 // this is the record 120 for id = 2
...
请注意,日期不遵循连续顺序(您可能在一行与下一行之间存在差距)。
我的问题是否有直接的SQL解决方案?(我知道我可以使用vba来实现我的目标,但我宁愿继续使用SQL)
作为澄清说明,请参阅此示例。给出以下结果集:
id date
-- ------
1 2015-01-12 // this is record 1 for id = 1
1 2015-01-13 // this is record 2 for id = 1
1 2015-01-20 // this is record 3 for id = 1
1 2015-01-21 // this is record 4 for id = 1
...
1 2015-03-22 // this is record 118 for id = 1
1 2015-03-23 // this is record 119 for id = 1
1 2015-03-24 // this is record 120 for id = 1
1 2015-03-25 // this is record 121 for id = 1
...
1 2015-06-30 // this is the last row for id = 1
2 2015-01-12 // this is record 1 for id = 2
2 2015-01-13 // this is record 2 for id = 2
...
2 2015-04-25 // this is record 120 for id = 2
...
2 2015-05-20 // this is the last record for id = 2
结果应为:
id date
-- --------
1 2015-03-24
2 2015-04-26
请记住,每个ID至少有120条记录,这是事实(我的查询只提供超过119条记录的ID)
我试图使用SELECT TOP
指令,但我未能达到我想要的结果,因为我无法直接应用它:我不想要前120名然后获得最后一行,因为我想要每个ID的最后一个TOP 120。
我的目标是拥有类似的东西:
SELECT id, 120thRow(date)
FROM table
GROUP BY id;
不幸的是,我不知道如何在访问中实现 120thRow 功能。
答案 0 :(得分:1)
这是否适用于Access?
select t.*
from table as t
where t.date = (select top 1 date
from (select top 120 date
from table t2
where t2.id = t.id
order by date
) as tt
order by date desc
);
编辑:
我猜MS Access不允许在关联子句中嵌套。你可以更痛苦地做到这一点:
select t.*
from table as t join
(select t.id, max(t.date) as maxdate
from table as t
where t.date = (select top 120 date
from table as t2
where t2.id = t.id
order by date
)
) tt
on t.id = tt.id and t.date = tt.maxdate;
答案 1 :(得分:1)
对不起我之前的回答,我误解了你。我有另一种方法,但在SQL中。我几乎可以肯定它在Access中不起作用,但可能会给你一个想法。
-- start: this is just preparation of some sample data
declare @t table (id int, date datetime)
declare @id int, @d datetime, @c int
set @c = 0
set @id = 1
set @d = '2015-01-01'
while @c <= 125
begin
insert into @t values (@id, @d)
set @d = dateadd(day, 1, @d)
set @c = @c + 1
end
set @c = 0
set @id = 2
set @d = '2015-01-02'
while @c <= 125
begin
insert into @t values (@id, @d)
set @d = dateadd(day, 1, @d)
set @c = @c + 1
end
-- end: this is just preparation of some sample data
-- this is somewhat like what you need:
select id, date from
(select id, date, row_number() over (partition by id order by date) as rc from @t) as mytable
where rc = 120
答案 2 :(得分:1)
最后,我设法为每天设置一个行计数器和ID,如下所示:
select id, date,
(
select count(date)
from table As t1
where t1.id = t.id
and t1.date <= t.date
) As rowNum
from table As t
从这里开始,只需从结果集中选择rownum = 120且游戏结束的行。
答案 3 :(得分:0)
嗨,我认为这一定对您有用。
with Records AS
(select row_number() over(order by sort_column_name) as 'row', *
from table_name) select * from records where row=n
sort_column_name
- 提及对表格进行排序的列的名称。n
- 行号table_name
- 提及表格表名称的名称