Sql server 无法将此查询正确分组

Sql server 无法将此查询正确分组,sql-server,Sql Server,tEmplHistory表具有员工的时间顺序记录。每个记录都有一个开始日期,指示该员工状态更改的时间。我需要拿出所有最接近但不超过某个给定日期的员工的所有记录。每位员工的记录将与该员工的给定日期前的记录一致。在输出中,我需要EmployistoryID,仅此而已。这就是我被困的地方: 这是表格: USE foo GO /****** Object: Table [dbo].[tEmplHistory] Script Date: 1/1/2017 6:12:54 PM ******/

tEmplHistory表具有员工的时间顺序记录。每个记录都有一个开始日期,指示该员工状态更改的时间。我需要拿出所有最接近但不超过某个给定日期的员工的所有记录。每位员工的记录将与该员工的给定日期前的记录一致。在输出中,我需要EmployistoryID,仅此而已。这就是我被困的地方:

这是表格:

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
对于此示例数据,我需要三个EmployHistoryID值:

9386 for EmplID = 2
9383 for EmplID = 2767
9376 for EmplID 2768
我需要拿出所有最接近但不超过某个给定日期的员工的所有记录

由于样本数据中的模糊日期,您的问题更难回答。在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
)

子查询为每个EmployHistoryID查找给定日期之前的最新开始日期。该日期和EmplyHistoryId被联接到外部表中的行,在本例中,外部表是同一个表

对于每个希望在给定日期之前获得最新记录的员工。因此,您选择该日期之前的记录,按日期对每个员工的记录进行排名,并保留最新记录:

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;

如果我们想吸引在2016-01-01之前状态发生变化的员工,下面的内容将起作用

    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

我建议手动输入查询,而不是使用查询设计器-设计器对于琐碎查询之外的任何查询都不够表达。您希望与起始日期进行比较的给定日期在哪里?我看不到您的表中包含此参数,所以我假设它是一个变量参数,您每次尝试创建此查询时都希望传入它?您有employees表吗?您的重点是SSMS。它生成了脚本。