2017-08-26 28 views
0

我有一個疑問,我很難把頭繞過。我需要更新基於以下條件的臨時表中的字段:用於更新臨時表的複雜查詢。可能派生的表格或相關的子查詢?

  • 我正在休假原因的員工,如果他們目前在休假
  • 的員工被認爲是休假,如果EmpSts是On Leave
  • 請假理由是從EmlChgRsn(就業變動原因)列,因此如果員工是在離開所期望的輸出將是在這種情況下
  • 記錄,其中EmlEfdDt IS NULL是最新的入門要麼FMLAFull BegFMLAInt Beg該員工。
  • 下面顯示了兩種不同類型的數據場景。第一個圖像是簡單的 - 如果EmlEfdDt IS NULL and EmlSts = "On Leave" and EmlChgRsn LIKE '%FMLA%',那麼只顯示EmlChgRsn。
  • 第二個形象是困難的一部分 - 自員工休假以來,例如主管變更和薪資調整等,對就業進行了一些調整。我需要搜索最新的EmlChgRsn,這是與假期有關的 - FMLAInt Beg

源數據可以大致如下:

enter image description here

OR

enter image description here

最後的結果,基於下面我有樣本數據,應該是這樣的: enter image description here

以下是一些示例數據以幫助您找出答案。請注意,我的第一遍傳遞簡單數據 - 如果您執行一兩次傳球或做一些事情想要一次更新所有內容,則無關緊要。我只需要得到'呃完成:)謝謝你的幫助!

--Create temp table to update 
CREATE TABLE #JobInfo (
Emp varchar(10) NULL 
,LeaveReason varchar(50) NULL 
); 
--Insert primer record with emp id's 
INSERT INTO #JobInfo 
VALUES (3750, '') 
    ,(3752, '') 

--Create source data table 
CREATE TABLE #Employment (
    Eml varchar(1) NULL 
    ,EmlChgRsn varchar(50) NULL 
    ,EmlEfdDt varchar(10) NULL 
    ,Emp varchar(10) NULL 
    ,EmpSts varchar(50) NULL 
); 

--Populate source data table with mock data 
INSERT INTO #Employment 
VALUES ('1', 'FMLAFull Beg', CONVERT(VARCHAR(10), DATEADD(MONTH, -6, GETDATE()), 101), '3752', 'On Leave') 
    ,('1', 'Salary', CONVERT(VARCHAR(10), DATEADD(MONTH, -5, GETDATE()), 101), '3752', 'On Leave') 
    ,('1', 'TeamChange', CONVERT(VARCHAR(10), DATEADD(MONTH, -4, GETDATE()), 101), '3752', 'On Leave') 
    ,('1', 'Salary', CONVERT(VARCHAR(10), DATEADD(MONTH, -3, GETDATE()), 101), '3752', 'On Leave') 
    ,('1', 'FMLAInt Beg', NULL, '3752', 'On Leave') 
    ,('1', 'Salary', CONVERT(VARCHAR(10), DATEADD(MONTH, -7, GETDATE()), 101), '3750', 'Active') 
    ,('1', 'FMLAFull Beg', CONVERT(VARCHAR(10), DATEADD(MONTH, -6, GETDATE()), 101), '3750', 'On Leave') 
    ,('1', 'Salary', CONVERT(VARCHAR(10), DATEADD(MONTH, -5, GETDATE()), 101), '3750', 'On Leave') 
    ,('1', 'New Supervisor', CONVERT(VARCHAR(10), DATEADD(MONTH, -4, GETDATE()), 101), '3750', 'On Leave') 
    ,('1', 'FMLAInt Beg', CONVERT(VARCHAR(10), DATEADD(MONTH, -3, GETDATE()), 101), '3750', 'On Leave') 
    ,('1', 'New Supervisor', NULL, '3750', 'On Leave') 

-- **First pass as updating the easy records 
UPDATE #JobInfo 
SET LeaveReason = (SELECT CASE WHEN (EmlChgRsn LIKE '%FMLA%Beg%' OR EmlChgRsn LIKE '%Leave%Beg%') 
          AND EmpSts = 'On Leave' THEN EmlChgRsn 

          ELSE '' END 
        FROM #Employment 
        WHERE #Employment.Emp = #JobInfo.Emp 
        AND EmlEfdDt IS NULL 
        AND Eml = 1) 

SELECT * 
FROM #JobInfo     
DROP TABLE #JobInfo 
DROP TABLE #Employment 

回答

1

這應該是你以後......

IF OBJECT_ID('tempdb..#JobInfo', 'U') IS NOT NULL 
DROP TABLE #JobInfo; 

CREATE TABLE #JobInfo (
    Emp varchar(10) NULL 
    ,LeaveReason varchar(50) NULL 
    ); 
--Insert primer record with emp id's 
INSERT INTO #JobInfo VALUES (3750, ''), (3752, ''); 

IF OBJECT_ID('tempdb..#Employment', 'U') IS NOT NULL 
DROP TABLE #Employment; 

CREATE TABLE #Employment (
    Eml varchar(1) NULL 
    ,EmlChgRsn varchar(50) NULL 
    ,EmlEfdDt varchar(10) NULL 
    ,Emp varchar(10) NULL 
    ,EmpSts varchar(50) NULL 
    ); 

--Populate source data table with mock data 
INSERT INTO #Employment 
VALUES ('1', 'FMLAFull Beg', CONVERT(VARCHAR(10), DATEADD(MONTH, -6, GETDATE()), 101), '3752', 'On Leave') 
    ,('1', 'Salary', CONVERT(VARCHAR(10), DATEADD(MONTH, -5, GETDATE()), 101), '3752', 'On Leave') 
    ,('1', 'TeamChange', CONVERT(VARCHAR(10), DATEADD(MONTH, -4, GETDATE()), 101), '3752', 'On Leave') 
    ,('1', 'Salary', CONVERT(VARCHAR(10), DATEADD(MONTH, -3, GETDATE()), 101), '3752', 'On Leave') 
    ,('1', 'FMLAInt Beg', NULL, '3752', 'On Leave') 
    ,('1', 'Salary', CONVERT(VARCHAR(10), DATEADD(MONTH, -7, GETDATE()), 101), '3750', 'Active') 
    ,('1', 'FMLAFull Beg', CONVERT(VARCHAR(10), DATEADD(MONTH, -6, GETDATE()), 101), '3750', 'On Leave') 
    ,('1', 'Salary', CONVERT(VARCHAR(10), DATEADD(MONTH, -5, GETDATE()), 101), '3750', 'On Leave') 
    ,('1', 'New Supervisor', CONVERT(VARCHAR(10), DATEADD(MONTH, -4, GETDATE()), 101), '3750', 'On Leave') 
    ,('1', 'FMLAInt Beg', CONVERT(VARCHAR(10), DATEADD(MONTH, -3, GETDATE()), 101), '3750', 'On Leave') 
    ,('1', 'New Supervisor', NULL, '3750', 'On Leave'); 

--============================================================================================== 

-- solution... 
UPDATE ji SET 
    ji.LeaveReason = x.LeaveReason 
FROM 
    #JobInfo ji 
    JOIN #Employment e1 
     ON ji.Emp = e1.Emp 
    CROSS APPLY (VALUES (CASE 
           WHEN e1.EmlChgRsn LIKE 'FMLA%' 
           THEN e1.EmlChgRsn 
           ELSE (
             SELECT TOP 1 
              e2.EmlChgRsn 
             FROM 
              #Employment e2 
             WHERE 
              e1.Emp = e2.Emp 
              AND e2.EmlChgRsn LIKE 'FMLA%' 
             ORDER BY 
              e2.EmlEfdDt DESC 
             ) 
         END)) x (LeaveReason) 
WHERE 
    e1.EmlEfdDt IS NULL 
    AND e1.EmpSts = 'On Leave'; 

SELECT * FROM #JobInfo ji; 

HTH,Jason

+0

我看到這給出了所需的輸出。我太累了,不能單獨挑選,以確保它是我所需要的,但我明天早上就會明白並接受是否結賬。謝謝傑森! –

0

看起來你只是想爲任何給定的員工最近出現fmlafull或fmlaint?

SELECT a.Eml, a.EmlChgRsn as LeaveReason FROM (

    SELECT 
    t.*, 
    ROW_NUMBER() OVER(PARTITION BY eml ORDER BY COALESCE(EmlEfdDt, GetDate()) DESC) as rown 
    FROM 
    employment t 
    INNER JOIN 
    (SELECT eml FROM employment WHERE EmlEfdDt IS NULL and EmpSts = 'On Leave') a 
    ON 
     t.eml = a.eml 
    WHERE 
    EmlChgRsn IN ('FMLAFull Beg', 'FMLAInt Beg') 
) a 
WHERE 
    a.rown = 1 

我們只選擇了FMLA全部或FMLA INT行,我們通過降日期的順序,給予任何無效的日期,現在,因爲它會那麼肯定是以後命令他們(如果不是,改變查詢到現在爲止的100年)。我們對第一行中最近的行進行編號,然後將其全部包裝在僅選擇編號爲1的行的查詢中。分區與groupby類似,行編號從1開始重新爲每個唯一的eml編號

如果您'再有變成一個更新這個改變JOBINFO表掙扎,讓我知道......我想你會沒事的那部分雖然

+0

我可能誤讀了(現在是凌晨2點),但這是我的印象。對於給定的emp(EmlEfdDt IS NULL),必須有EmpSts ='On Leave'...所以這不僅僅是找到最受歡迎的EmlChgRsn IN('FMLAFull Beg','FMLAInt Beg') –

+0

正確的問題。如果最近一排有'休假'的EmpSts,那麼他們正在休假。如果沒有,那麼我現在不關心這個問題。 –

+0

我添加了一個內部連接來限制查詢,只查看當前正在請假的員工 –