2017-01-01 77 views
0

tEmplHistory表具有針對員工的按時間順序排列的記錄。每條記錄都有一個開始日期,指示該員工的狀態更改時間。我需要爲最接近但不超過給定日期的所有員工記錄所有記錄。每個員工的記錄將在該員工的特定日期之前。在輸出中我需要EmplHistoryID,就是這樣。這其中,我卡:無法將此查詢正確分組

This is where I'm stuck 下面是表:

USE foo 
GO 

/****** Object: Table [dbo].[tEmplHistory] Script Date: 1/1/2017 6:12:54 PM ******/ 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [dbo].[tEmplHistory](
    [EmplHistoryID] [int] IDENTITY(1,1) NOT NULL, 
    [StartDate] [datetime] NOT NULL, 
    [EmplStatusID] [int] NOT NULL, 
    [Comment] [nvarchar](max) NULL, 
    [DateStamp] [datetime] NOT NULL, 
    [EmplID] [int] NOT NULL, 
CONSTRAINT [PK_tEmplHistory] PRIMARY KEY CLUSTERED 
(
    [EmplHistoryID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

GO 

下面是一些數據:

INSERT 
    [dbo].[tEmplHistory] 
    ([EmplHistoryID], [StartDate], [EmplStatusID], [Comment], [DateStamp], [EmplID]) 
VALUES 
    (9375, CAST(0x0000A6EE0104A007 AS DateTime), 1, NULL, CAST(0x0000A6EE0104A007 AS DateTime), 2768), 
    (9376, CAST(0x0000A58000000000 AS DateTime), 1, NULL, CAST(0x0000A6EE010B2D97 AS DateTime), 2768), 
    (9377, CAST(0x0000A43100000000 AS DateTime), 1, NULL, CAST(0x0000A6EE010B481D AS DateTime), 2768), 
    (9378, CAST(0x0000A58100000000 AS DateTime), 1, NULL, CAST(0x0000A6EE010B591F AS DateTime), 2768), 
    (9379, CAST(0x0000A57F00000000 AS DateTime), 1, NULL, CAST(0x0000A6EE010B6F5C AS DateTime), 2768), 
    (9380, CAST(0x0000A57E00000000 AS DateTime), 1, NULL, CAST(0x0000A6EE010B7AB7 AS DateTime), 2768), 
    (9381, CAST(0x0000A58100000000 AS DateTime), 1, NULL, CAST(0x0000A6EE010B9343 AS DateTime), 2768), 
    (9382, CAST(0x0000A58200000000 AS DateTime), 2, NULL, CAST(0x0000A6EE01188D3E AS DateTime), 2767), 
    (9383, CAST(0x0000A57F00000000 AS DateTime), 2, NULL, CAST(0x0000A6EE011903FF AS DateTime), 2767), 
    (9384, CAST(0x0000A57E00000000 AS DateTime), 2, NULL, CAST(0x0000A6EE01194FF5 AS DateTime), 2767), 
    (9385, CAST(0x0000A58100000000 AS DateTime), 1, NULL, CAST(0x0000A6EE012780A6 AS DateTime), 2), 
    (9386, CAST(0x0000A58000000000 AS DateTime), 2, NULL, CAST(0x0000A6EE01278D59 AS DateTime), 2), 
    (9387, CAST(0x0000A57F00000000 AS DateTime), 3, NULL, CAST(0x0000A6EE0127A45A AS DateTime), 2) 

    SET IDENTITY_INSERT [dbo].[tEmplHistory] OFF 
    GO 

對於這個樣本數據我需要三個EmplHistoryID值:

9386 for EmplID = 2 
9383 for EmplID = 2767 
9376 for EmplID 2768 
+1

我建議用手鍵入查詢,而不是使用查詢設計 - 設計者是不是什麼了超越平凡的查詢足夠的表現力。 – Dai

+0

您想與StartDate比較的「給定日期」在哪裏?我沒有看到這包括在你的表中,所以我假設你想在每次創建這個查詢時都要傳遞一個可變參數? – Edward

+0

你有'員工'表嗎? –

回答

0

我需要爲最接近但不超過某個給定日期的所有員工記錄所有記錄。

由於樣本數據中的混淆日期,您的問題更難以回答。在20年的T-SQL工作中,這是我第一次看到明確轉換爲datetime的二進制值。通常,文字值是以字符串形式提供的。

儘管如此,查詢的基本形式並不複雜。你想所有記錄日期前確定的,不只是一個,所以

select * from tEmplHistory where StartDate < '1/1/1990' 

或任何日期想指定。

但也許這不是你的意思?也許你的意思是單行爲每個員工之前和最近的某個日期確定?對於要一個相關子查詢:

select * from tEmplHistory as H where exists (
    select 1 from tEmplHistory 
    where EmplHistoryID = H.EmplHistoryID 
    and StartDate < '1/1/1990' 
    group by EmplHistoryID 
    having max(StartDate) = H.StartDate 
) 

子查詢發現之前,每個EmplHistoryID給定的日期最新的開始日期。該日期和EmplHistoryID被連接到外部表中的行(在本例中是同一個表)。

+0

你的牛肉與SSMS。它生成了腳本。 – nicomp

0

對於每位員工,您希望在給定日期之前獲得最新記錄。所以,你選擇該日之前的記錄,按日期排序每名僱員的紀錄,並保持最新:

select emplid, emplhistoryid 
from 
(
    select 
    emplid, 
    emplhistoryid, 
    row_number() over(partition by emplid order by datestamp desc) as rn 
    from templhistory eh 
    where datestamp <= '20161231' 
) ranked 
where rn = 1; 
0

如果我們想拉2016年1月1日之前,其狀態改變了員工的下方會工作。

SELECT EMPLHISTORYID ,EMPID FROM 
(
    SELECT EMPLHISTORYID,[EmplID] AS EMPID, 
    STARTDATE,RANK() OVER (PARTITION BY [EmplID] ORDER BY StarttDate Desc) as RNK 
FROM [dbo].[tEmplHistory] 
WHERE startDATE <='2016-01-01 00:00:00' 
)A 
WHERE A.RNK=1