簡體   English   中英

按 Row_Number 函數中的兩列進行分區

[英]Partition By over Two Columns in Row_Number function

我正在嘗試使用以下查詢對記錄進行排名:

SELECT 
ROW_NUMBER() over (partition by 
TW.EMPL_ID,TW.HR_DEPT_ID,TW.Transfer_Startdate 
order by TW.EMPL_ID,TW.Effective_Bdate) RN,
TW.EMPL_ID,TW.HR_DEPT_ID,TW.Transfer_Startdate,Effective_BDate from 
TT_EMPLOYEE_WORKDAY TW
where TW.HR_DOMAIN_CODE = 'SGP'

但是,生成的 Row_Number 計算列僅顯示第一列的分區。 理想情況下,我希望 Row_Number 具有相同的值,其中按列數據進行分區是相同的。

任何線索我可能會出錯?

USING RANK 或 DENSE RANK 不是一個選項,因為我想為多個員工識別所有此類行,其中 EMPL_ID、HR_DEPT_ID 和 Transfer_StartDate 相同(RN = 1)

Sample data:
RN  AON_EMPL_ID   HR_DEPT_ID    Transfer_Startdate  Effective_BDate
1   0100690       69895             01/01/2017       2017-01-01
2   0100690       69895             01/01/2017       2017-01-03
3   0100690       69895             01/01/2017       2017-01-04
SELECT 
RANK() over (partition by   --or DENSE_RANK()
TW.EMPL_ID,TW.HR_DEPT_ID,TW.Transfer_Startdate 
order by TW.EMPL_ID,TW.Effective_Bdate) RN,
TW.EMPL_ID,TW.HR_DEPT_ID,TW.Transfer_Startdate,Effective_BDate from 
TT_EMPLOYEE_WORKDAY TW
where TW.HR_DOMAIN_CODE = 'SGP'

更新

SELECT 
RANK() over (partition by   --or DENSE_RANK()
TW.EMPL_ID,TW.HR_DEPT_ID,TW.Transfer_Startdate 
order by TW.EMPL_ID) RN,
TW.EMPL_ID,TW.HR_DEPT_ID,TW.Transfer_Startdate,Effective_BDate from 
TT_EMPLOYEE_WORKDAY TW
where TW.HR_DOMAIN_CODE = 'SGP'
Order by RN,TW.Effective_Bdate

將樣本數據擴展為:

create table t (
    aon_empl_id varchar(16)
  , hr_dept_id varchar(16)
  , Transfer_Startdate date
  , Effective_bdate date
);
insert into t values 
 ('0100690','69895','01/01/2017','2017-01-01')
,('0100690','69895','01/01/2017','2017-01-03')
,('0100690','69895','01/01/2017','2017-01-04')
,('0200700','69895','01/01/2016','2016-01-01')
,('0200700','69895','01/01/2016','2016-01-03')
,('0200700','69896','01/01/2017','2017-01-04')
,('0200700','69896','01/01/2017','2017-01-04');

使用top with ties

select top 1 with ties
    aon_empl_id
  , hr_dept_id
  , Transfer_Startdate = convert(char(10),Transfer_Startdate,120)
  , Effective_bdate    = convert(char(10),Effective_bdate,120)
from t
order by row_number() over (
      partition by aon_empl_id, hr_dept_id, Transfer_Startdate 
      order by Effective_bdate
      )

reextester 演示: http ://rextester.com/KOIZ42069

返回:

+-------------+------------+--------------------+-----------------+
| aon_empl_id | hr_dept_id | Transfer_Startdate | Effective_bdate |
+-------------+------------+--------------------+-----------------+
|     0100690 |      69895 | 2017-01-01         | 2017-01-01      |
|     0200700 |      69895 | 2016-01-01         | 2016-01-01      |
|     0200700 |      69896 | 2017-01-01         | 2017-01-04      |
+-------------+------------+--------------------+-----------------+

使用帶有row_number()公共表表達式的替代方法:

;with cte as (
select
    rn = row_number() over (
      partition by aon_empl_id, hr_dept_id, Transfer_Startdate 
      order by Effective_bdate
    )
  , aon_empl_id
  , hr_dept_id
  , Transfer_Startdate = convert(char(10),Transfer_Startdate,120)
  , Effective_bdate    = convert(char(10),Effective_bdate,120)
from t tw
)

select *
from cte
where rn = 1

返回:

+----+-------------+------------+--------------------+-----------------+
| rn | aon_empl_id | hr_dept_id | Transfer_Startdate | Effective_bdate |
+----+-------------+------------+--------------------+-----------------+
|  1 |     0100690 |      69895 | 2017-01-01         | 2017-01-01      |
|  1 |     0200700 |      69895 | 2016-01-01         | 2016-01-01      |
|  1 |     0200700 |      69896 | 2017-01-01         | 2017-01-04      |
+----+-------------+------------+--------------------+-----------------+

這段代碼似乎正在工作:

SELECT 
dense_rank() over (partition by AON_EMPL_ID 
order by AON_EMPL_ID,HR_DEPT_ID,Transfer_StartDate) RN,
TW.AON_EMPL_ID,TW.HR_DEPT_ID,TW.Transfer_Startdate,Effective_BDate from 
TT_AON_EMPLOYEE_WORKDAY TW
where TW.HR_DOMAIN_CODE = 'SGP'

顯然,我只需要按 AON_EMPL_ID 進行分區,其他所有內容都應該轉到 Order By 子句。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM