SQL 查询 table 中每个批次的顶部和底部行 select

SQL Query select top and bottom rows from every batch in the table

我有如下一堆数据,我已经从数据库中提取并订购了。

ExecutionTime            BatchKey   Account   Instrument    UserName
2020-10-16 17:27:03.600     1        1234      ABOK        HornedFrogs
2020-10-16 17:27:03.600     1        EGO321    ABOK        HouseAccount
2020-10-16 21:14:04.483     1        EGO321    ABOK        HouseAccount
2020-10-16 21:14:04.483     1        1234      ABOK        BrokerAccount
2020-10-16 14:28:10.973     2        1098      ABOK        BaylorBears
2020-10-16 14:28:10.973     2        EGO321    ABOK        HouseAccount
2020-10-16 14:28:10.973     2        EGO321    ABOK        HouseAccount
2020-10-16 14:28:10.973     2        1234      ABOK        BrokerAccount
2020-10-16 21:14:04.473     2        EGO321    ABOK        BrokerAccount
2020-10-16 21:14:04.473     2        1234      ABOK        CustodianAccount
2020-10-16 12:26:21.503     3        1098      ABOK        SMUMustangs
2020-10-16 12:26:21.503     3        EGO321    ABOK        HouseAccount
2020-10-16 12:26:21.503     3        EGO321    ABOK        HouseAccount
2020-10-16 12:26:21.503     3        1234      ABOK        BrokerAccount
2020-10-16 21:14:04.377     3        EGO321    ABOK        BrokerAccount
2020-10-16 21:14:04.377     3        1234      ABOK        CustodianAccount
2020-10-16 07:14:04.411     4        1234      ABOK        BrokerAccount

以上数据是由BatchKey组织的,所以BatchKey中的所有内容都组合在一起。

每个BatchKey都是按照ExecutionTime排序的,所以最早的在最上面,最新的在最下面。

我想将其用作较小的 table,并根据以下逻辑提取行:

对于每个 BatchKey:

-if the BatchKey has more than 2 entries, select the earliest (top) and the latest (bottom) entries in the batch

-if the BatchKey has exactly 2 entries, select them

-(else) if the BatchKey has only 1 entry, select it

结果应如下所示:

查询应提取以下行

ExecutionTime            BatchKey   Account   Instrument    UserName
2020-10-16 17:27:03.600     1        1234      ABOK        HornedFrogs
2020-10-16 21:14:04.483     1        1234      ABOK        BrokerAccount
2020-10-16 14:28:10.973     2        1098      ABOK        BaylorBears
2020-10-16 21:14:04.473     2        1234      ABOK        CustodianAccount
2020-10-16 12:26:21.503     3        1098      ABOK        SMUMustangs
2020-10-16 21:14:04.377     3        1234      ABOK        CustodianAccount
2020-10-16 07:14:04.411     4        1234      ABOK        BrokerAccount

有什么方法可以 运行 在 SQL 中进行这样的查询吗?

使用row_number():

select *
from (
    select t.*, 
        row_number() over(partition by batchkey order by executiontime) rn_asc,
        row_number() over(partition by batchkey order by executiontime desc) rn_desc
    from mytable t
) t
where 1 in (rn_asc, rn_desc)

逻辑是对batchkey相同的记录按executiontime升序和降序排列,然后过滤最上面和最下面的行号。如果给定的 batchkey 只有一个记录,则它在两个方向上的排名都是 1