SQL Server:保持dense_rank的最后一个顺序

时间:2015-04-06 09:41:55

标签: sql sql-server oracle

我在Oracle上有以下查询

select 
        max(DW_EXTRACT_DATE)                as DW_EXTRACT_DATE, 
        DW_LOGICAL_DATE     as SELECTION_DATE, 
        max(DW_LOGICAL_DATE)                as DW_LOGICAL_DATE, 
        max(RUNTIME_AUDIT_ID)               as RUNTIME_AUDIT_ID, 
        max(REC_SRC_SYS)                as REC_SRC_SYS, 
        POSITION_ID, 
        EMPLOYEE_ID,  
            PRIMARY_POS,
            INV_STR_DATE,
            max(POS_STOP_DATE) keep (dense_rank last order by INV_STR_DATE)     as POSITION_STOP_DATE,
            max(CHANGE_REASON) keep (dense_rank last order by INV_STR_DATE)     as CHANGE_REASON_CD,
            max(ACTUAL_FTE_PERC) keep (dense_rank last order by INV_STR_DATE)   as ACTUAL_FTE_PERC
      from 
        EMPLOYEE_POSITION 
      where
        POSITION_ID      != 'TERMINATED'
      group by 
        DW_LOGICAL_DATE, 
        POSITION_ID, 
        EMPLOYEE_ID, 
        PRIMARY_POS, 
        INV_STR_DATE

如何用sql server做同样的事情?我是oracle的新人。

我尝试了以下查询。

SELECT  DW_EXTRACT_DATE,DW_LOGICAL_DATE,RUNTIME_AUDIT_ID,REC_SRC_SYS,REC_SRC_SYS,POSITION_ID,

        EMPLOYEE_ID,  PRIMARY_POS,INV_STR_DATE,POS_STOP_DATE,
            CHANGE_REASON,
            ACTUAL_FTE_PERC
FROM (  SELECT *, ROW_NUMBER() OVER(PARTITION BY POS_STOP_DATE ORDER BY INV_STR_DATE DESC) Corr
        FROM EMPLOYEE_POSITION
         where POSITION_ID      != 'TERMINATED') A WHERE Corr = 1

1 个答案:

答案 0 :(得分:3)

在SQL Server 2012+中,您可以使用FIRST_VALUE()

所以(为了简单起见):

SELECT max(POS_STOP_DATE) keep (dense_rank last order by INV_STR_DATE) as POSITION_STOP_DATE
FROM EMPLOYEE_POSITION
GROUP BY X;

可以用SQL Server 2012+编写:

SELECT MAX(POSITION_STOP_DATE)
FROM (SELECT ep.*,
             FIRST_VALUE(POS_STOP_DATE) OVER (PARTITION BY X ORDER BY INV_STR_DATE DESC) as POSITION_STOP_DATE
      FROM EMPLOYEE_POSITION ep
     ) ep
GROUP BY x;

在SQL Server 2005+中,您可以使用ROW_NUMBER()和条件聚合:

执行此操作
SELECT MAX(CASE WHEN seqnum = 1 THEN POS_STOP_DATE END) as POSITION_STOP_DATE)
FROM (SELECT ep.*,
             ROW_NUMBER() OVER (PARTITION BY X ORDER BY INV_STR_DATE DESC) as seqnum
      FROM EMPLOYEE_POSITION ep
     ) ep
GROUP BY x;