假设我有一张包含以下记录的表
Name Seq Join Resign
---------------- ---------------------------------------- ----------------------------
Joe 1 2001-11-04 00:00:00.000 2005-03-31 00:00:00.000
Joe 2 2005-04-01 00:00:00.000 NULL
Jane 1 2011-12-04 00:00:00.000 2013-02-01 00:00:00.000
Jane 2 2015-05-01 00:00:00.000 NULL
Jack 1 2001-01-01 00:00:00.000 2002-01-01 00:00:00.000
Jack 2 2002-01-02 00:00:00.000 2003-01-01 00:00:00.000
Jack 3 2005-01-01 00:00:00.000 2006-01-01 00:00:00.000
Jack 4 2006-01-02 00:00:00.000 NULL
所以我试图找出员工Join Date
,Seq
代表雇佣号码,所以如果员工辞职并且稍后重新加入公司,Seq
将会增加。但是当员工获得晋升或搬到另一个部门时,问题是Seq
也会增加。
在我的情况下,Joe有2 Seq
但他从未辞职,因为他的第二个加入日期=辞职日期+ 1.所以我的最终预期结果是
知道如何在不循环的情况下获得此结果吗?
注意:Seq
可以是1,2,3,4等等取决于每位员工的晋升或辞职/重新加入次数
杰克预期结果是2005-01-01
,因为从第一名雇员到第二名雇员并不是真正的辞职,因为第二次雇用JoinDate =第一次雇用ResignDate + 1 2002-01-01 = 2002-01-02 + 1
。但从第二次雇用到第三次雇用实际上是因为2003-01-01 != 2005-01-01 + 1
而辞职。我希望这是有道理的。
答案 0 :(得分:1)
我想你可以试试这个:
SELECT B.NAME, JJOIN
FROM (SELECT *
, LAG(DD1) OVER (PARTITION BY NAME ORDER BY RMAX) AS DD1_PREC
FROM
(
SELECT *
, ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY SEQ DESC) AS RMAX
, LEAD(RESIGN) OVER (PARTITION BY NAME ORDER BY SEQ DESC) AS PREC_RESIGN
, DATEDIFF(dd,LEAD(RESIGN) OVER (PARTITION BY NAME ORDER BY SEQ DESC),JJOIN) AS DD1
FROM TABLEX) A
) B
WHERE (RMAX =1 AND DD1>1 )
OR (RMAX = 2 AND DD1_PREC<=1)
输出:
NAME JJOIN
-------------------- -----------------------
Jack 2005-01-01 00:00:00.000
Jane 2015-05-01 00:00:00.000
Joe 2010-11-04 00:00:00.000
答案 1 :(得分:0)
这更容易理解
;WITH cte AS (
SELECT res.*,
--df = 0 if join and resign dates have difference greater than 1 else df = 1
DATEDIFF(Day, IsNull(jn.Resign, res.JoinDate), res.JoinDate) df,
ROW_NUMBER() OVER (PARTITION BY res.Name ORDER BY res.Name DESC) AS rn
FROM [dbo].[tblWarheat1990] res
LEFT JOIN [dbo].[tblWarheat1990] jn ON res.JoinDate = DATEADD(day, 1, jn.Resign)
)
, gte as (
SELECT *,
ROW_NUMBER() OVER (partition by name ORDER BY rn DESC) AS minimum
FROM cte
WHERE df = 0)
SELECT * FROM gte WHERE minimum = 1
ORDER BY rn DESC
答案 2 :(得分:-1)
您希望前一天没有join
日期的最长resign
日期。
我会这样做:
select t.name, max(t.join)
from t left join
t tprev
on t.join = dateadd(day, 1, tprev.resign)
where t.prev.resign is null
group by name;
或者,您可以使用seq
和lag()
:
select name, max(join)
from (select t.*,
lag(t.resign) over (partition by t.name order by t.seq) as prev_resign
from t
) t
where prev_resign is null or prev_resign <> dateadd(day, -1, resign)
group by name;