簡體   English   中英

如何在SQL中比較同一表中的同一列?

[英]How to compare same column in the same table in SQL?

假設我有一個包含以下記錄的表

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

因此,我試圖找出Employee Join DateSeq表示雇用人數,因此,如果某個雇員辭職並隨后重新加入公司,則Seq將會增加。 但是問題在於,當員工獲得升職或移至另一個部門時, Seq也會增加。

在我的情況下,喬有2個Seq但他從未辭職,因為他的第二個加入日期=辭職日期+1。所以我的最終預期結果是

  • 喬,2001-11-04
  • 簡,2015-05-01
  • 傑克(Jack),2005年1月1日(因為他在第二次雇用后辭職了)

任何想法如何獲得此結果而不循環?

注意: Seq可以是1,2,3,4,依此類推取決於每個員工升職或辭職/重新加入的人數

傑克預期的結果是2005-01-01 ,因為從1日到租金第二是不實際的,因為辭職租用2號= JoinDate 1租賃ResignDate + 1 2002-01-01 = 2002-01-02 + 1 但是實際上從第二次雇用到第三次雇用是辭職,因為2003-01-01 != 2005-01-01 + 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

這更容易理解

;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

您需要最大的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;

另外,您可以使用seqlag()進行此操作:

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;

暫無
暫無

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

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