访问每个给定字段的 SQL return 第 n 行
Access SQL return nth row for each given field
我的问题
假设我有一个查询 returns 以下数据:
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;
不幸的是,我不知道如何在 access 中实现 120thRow 函数。
这在 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;
抱歉我之前的回答,我误会了你。我有另一种方法,但在 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
最后,我设法为每一天和 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 的行并结束游戏即可。
嗨,我想这一定对你有用。
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
– 提及对 table. 进行排序的列的名称
n
– 行号
table_name
– 提到 table table name 的名字
我的问题
假设我有一个查询 returns 以下数据:
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;
不幸的是,我不知道如何在 access 中实现 120thRow 函数。
这在 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;
抱歉我之前的回答,我误会了你。我有另一种方法,但在 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
最后,我设法为每一天和 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 的行并结束游戏即可。
嗨,我想这一定对你有用。
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
– 提及对 table. 进行排序的列的名称
n
– 行号table_name
– 提到 table table name 的名字