Emi*_*ing 7 sql t-sql sql-server sql-server-2014
问:如何根据1列的变化值对记录进行排名?
我有以下数据(https://pastebin.com/vdTb1JRT):
EmployeeID Date Onleave
ABH12345 2016-01-01 0
ABH12345 2016-01-02 0
ABH12345 2016-01-03 0
ABH12345 2016-01-04 0
ABH12345 2016-01-05 0
ABH12345 2016-01-06 0
ABH12345 2016-01-07 0
ABH12345 2016-01-08 0
ABH12345 2016-01-09 0
ABH12345 2016-01-10 1
ABH12345 2016-01-11 1
ABH12345 2016-01-12 1
ABH12345 2016-01-13 1
ABH12345 2016-01-14 0
ABH12345 2016-01-15 0
ABH12345 2016-01-16 0
ABH12345 2016-01-17 0
Run Code Online (Sandbox Code Playgroud)
我想产生以下结果:
EmployeeID DateValidFrom DateValidTo OnLeave
ABH12345 2016-01-01 2016-01-09 0
ABH12345 2016-01-10 2016-01-13 1
ABH12345 2016-01-14 2016-01-17 0
Run Code Online (Sandbox Code Playgroud)
所以我想我是否可以以某种方式创建一个排名列(如下所示),该列根据Onleave列中的值递增 - 由EmployeeID列分区.
EmployeeID Date Onleave RankedCol
ABH12345 2016-01-01 0 1
ABH12345 2016-01-02 0 1
ABH12345 2016-01-03 0 1
ABH12345 2016-01-04 0 1
ABH12345 2016-01-05 0 1
ABH12345 2016-01-06 0 1
ABH12345 2016-01-07 0 1
ABH12345 2016-01-08 0 1
ABH12345 2016-01-09 0 1
ABH12345 2016-01-10 1 2
ABH12345 2016-01-11 1 2
ABH12345 2016-01-12 1 2
ABH12345 2016-01-13 1 2
ABH12345 2016-01-14 0 3
ABH12345 2016-01-15 0 3
ABH12345 2016-01-16 0 3
ABH12345 2016-01-17 0 3
Run Code Online (Sandbox Code Playgroud)
然后我就能做到以下几点:
SELECT
[EmployeeID] = [EmployeeID]
,[DateValidFrom] = MIN([Date])
,[DateValidTo] = MAX([Date])
,[OnLeave] = [OnLeave]
FROM table/view/cte/sub-query
GROUP BY
[EmployeeID]
,[OnLeave]
,[RankedCol]
Run Code Online (Sandbox Code Playgroud)
其他解决方案非常受欢迎..
以下是测试数据:
WITH CTE AS ( SELECT EmployeeID = 'ABH12345', [Date] = CAST(N'2016-01-01' AS Date), [Onleave] = 0
UNION SELECT 'ABH12345', CAST(N'2016-01-02' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-03' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-04' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-05' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-06' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-07' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-08' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-09' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-10' AS Date), 1
UNION SELECT 'ABH12345', CAST(N'2016-01-11' AS Date), 1
UNION SELECT 'ABH12345', CAST(N'2016-01-12' AS Date), 1
UNION SELECT 'ABH12345', CAST(N'2016-01-13' AS Date), 1
UNION SELECT 'ABH12345', CAST(N'2016-01-14' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-15' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-16' AS Date), 0
UNION SELECT 'ABH12345', CAST(N'2016-01-17' AS Date), 0
)
SELECT * FROM CTE
Run Code Online (Sandbox Code Playgroud)
这是另一种更简单的方法来获得所需的输出 - 仅访问该表一次。
-- sample of data from your question
with t1(EmployeeID, Date1, Onleave) as(
select 'ABH12345', cast('2016-01-01' as date), 0 union all
select 'ABH12345', cast('2016-01-02' as date), 0 union all
select 'ABH12345', cast('2016-01-03' as date), 0 union all
select 'ABH12345', cast('2016-01-04' as date), 0 union all
select 'ABH12345', cast('2016-01-05' as date), 0 union all
select 'ABH12345', cast('2016-01-06' as date), 0 union all
select 'ABH12345', cast('2016-01-07' as date), 0 union all
select 'ABH12345', cast('2016-01-08' as date), 0 union all
select 'ABH12345', cast('2016-01-09' as date), 0 union all
select 'ABH12345', cast('2016-01-10' as date), 1 union all
select 'ABH12345', cast('2016-01-11' as date), 1 union all
select 'ABH12345', cast('2016-01-12' as date), 1 union all
select 'ABH12345', cast('2016-01-13' as date), 1 union all
select 'ABH12345', cast('2016-01-14' as date), 0 union all
select 'ABH12345', cast('2016-01-15' as date), 0 union all
select 'ABH12345', cast('2016-01-16' as date), 0 union all
select 'ABH12345', cast('2016-01-17' as date), 0
)
-- actual query
select max(w.employeeid) as employeeid
, min(w.date1) as datevalidfrom
, max(w.date1) as datevalidto
, max(w.onleave) as onleave
from (
select row_number() over(partition by employeeid order by date1) -
row_number() over(partition by employeeid, onleave order by date1) as grp
, employeeid
, date1
, onleave
from t1 s
) w
group by w.grp
order by employeeid, datevalidfrom
Run Code Online (Sandbox Code Playgroud)
结果:
employeeid datevalidfrom datevalidto onleave
---------- ------------- ----------- -----------
ABH12345 2016-01-01 2016-01-09 0
ABH12345 2016-01-10 2016-01-13 1
ABH12345 2016-01-14 2016-01-17 0
Run Code Online (Sandbox Code Playgroud)