SQL Server Query group by analytic

时间:2018-01-27 14:25:48

标签: sql sql-server group-by

我有一张这样的表

Id scid  name  namesuffix nameId namesuffixid  fullname
--------------------------------------------------------
1   1    a     a          100    100            a
2   1    a     b          100    101            ab
3   1    b     c          101    102            abc
4   1    c     d          102    103            abcd 
5   2    e     e          104    104            e
6   2    e     f          104    105            ef
7   2    f     g          105    106            efg
8   3    i     i          107    107            i
9   3    i     j          107    108            ij 
10  3    j     k          108    109            ijk
11  3    k     l          109    110            ijkl
12  3    l     m          110    111            ijklm


for each scid (group by scid) 
    select firstRow fullName
         Last row fullName

预期输出

id scid  fullname
-------------------
1  1     a
4  1     abcd
5  2     e
7  2     efg
8  3     i
12 3     ijklm

我尝试了first_valuelast_value分析函数,但行重复,没有得到预期的结果。

任何帮助表示感谢。

3 个答案:

答案 0 :(得分:0)

您可以按照建议使用FIRST_VALUELAST_VALUE

SELECT scid,
     FIRST_VALUE(id) OVER(PARTITION BY scid ORDER BY id 
                          ROWS UNBOUNDED PRECEDING) AS id,
     FIRST_VALUE(fullname) OVER(PARTITION BY scid ORDER BY id 
                           ROWS UNBOUNDED PRECEDING) AS fullname
FROM tab_name
UNION 
SELECT scid,
     LAST_VALUE(id) OVER(PARTITION BY scid ORDER BY id 
                   RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS id,
     LAST_VALUE(fullname) OVER(PARTITION BY scid ORDER BY id
                   RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS fullname
FROM tab_name
ORDER BY scid, id;

<强> Demo

答案 1 :(得分:0)

另一种选择是使用ROW_NUMBER()COUNT

select
    id, scid, fullname
from (
    select
        *, row_number() over (partition by scid order by id) rn
        , count(*) over (partition by scid) cnt
    from
        myTable
) t
where
    rn = 1 
    or rn = cnt

答案 2 :(得分:0)

还有其他方法可以在没有窗口功能的情况下执行此操作:

select t.*
from t join
     (select min(id) as min_id, max(id) as max_id
      from t
      group by sc_id
     ) tt
     on t.id in (min_id, max_id);

我只是建议这样做,因为有很多方法可以做你想要的。如果性能存在问题,您可能需要尝试不同的方法。