访问每个给定字段的 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
  • 的名字