我在SQL Server 2008 R2中链接了MAS(会计系统)的数据库。工资单记录在此数据库中的工作方式是每个季度,工资表的存档,以及删除任何已终止员工的新当前季度表。它确实有唯一的员工ID。存档和当前版本的结构相同。
因此,在今年第二季度,第一季度被终止的员工仅在数据库的第一季度副本中。在第1季度和第2季度工作的员工是第1季度副本和第2季度副本。第二季度雇用的员工仅在第二季度出现。
我需要能够构建一个集合(临时表,视图等),包括每个员工的最新记录。该集合将成为诸如营业额,按职位平均工资等查询的基础。
我可以使用UNION
列的EmployeeID
快速建立ID列表,但其他列会随着时间的推移而变化(付费率,地址等),所以我不能简单地{{1所有列,因为我将为一些员工提供重复。
是否有合理有效的方法将历史数据库合并在一起,只保留每个员工的最新行?以这种方式提出问题,我是否应该制作一系列UNION
s,从最新到最旧的档案副本退回,在不匹配时插入?还有更好的方法吗?
答案 0 :(得分:0)
有几种方法可以解决这个问题。这是一个:
创建示例表模式和测试数据
SET NOCOUNT ON
IF OBJECT_ID('Employee', 'U') IS NOT NULL DROP TABLE Employee;
GO
IF OBJECT_ID('Employee2012Q1', 'U') IS NOT NULL DROP TABLE Employee2012Q1;
GO
IF OBJECT_ID('Employee2012Q2', 'U') IS NOT NULL DROP TABLE Employee2012Q2;
GO
CREATE TABLE dbo.Employee (
EmployeeID int IDENTITY(1,1) NOT NULL PRIMARY KEY
,EmployeeName varchar(50) NOT NULL
,StartDate smalldatetime NOT NULL
,EndDate smalldatetime NULL
,Salary decimal(18,2) NOT NULL
,Position varchar(50) NOT NULL
,HomeAddress varchar(200) NOT NULL
)
-- Employees hired
INSERT dbo.Employee SELECT 'John Doe', '01/01/2012', NULL, 50000, 'Developer', '12345 Main St, New York, NY'
INSERT dbo.Employee SELECT 'Jane Doe', '01/01/2012', NULL, 52000, 'Developer', '837 1st St, New York, NY'
-- Employee fired
UPDATE A
SET A.EndDate = '02/01/2012'
FROM dbo.Employee A
WHERE A.EmployeeName = 'John Doe'
-- Table archived
SELECT * INTO dbo.Employee2012Q1 FROM dbo.Employee
-- Remove fired employees
DELETE dbo.Employee WHERE EndDate IS NOT NULL
-- Employee hired
INSERT dbo.Employee SELECT 'Jack Flash', '04/01/2012', NULL, 73000, 'Manager', '9580 21st St, New York, NY'
-- Employee fired
UPDATE A
SET A.EndDate = '05/01/2012'
FROM dbo.Employee A
WHERE A.EmployeeName = 'Jack Flash'
-- Table archived
SELECT * INTO dbo.Employee2012Q2 FROM dbo.Employee
-- Remove fired employees
DELETE dbo.Employee WHERE EndDate IS NOT NULL
SET NOCOUNT OFF
GO
创建合并所有员工表的视图
IF OBJECT_ID('EmployeeArchive', 'V') IS NOT NULL DROP VIEW dbo.EmployeeArchive
GO
CREATE VIEW dbo.EmployeeArchive
AS
SELECT CONVERT(smalldatetime, CONVERT(char(10), GETDATE(), 101)) as [ArchiveDate]
,EmployeeID
,EmployeeName
,StartDate
,EndDate
,Salary
,Position
,HomeAddress
FROM dbo.Employee
UNION ALL
SELECT CONVERT(smalldatetime, '03/31/2012') as [ArchiveDate]
,EmployeeID
,EmployeeName
,StartDate
,EndDate
,Salary
,Position
,HomeAddress
FROM dbo.Employee2012Q1
UNION ALL
SELECT CONVERT(smalldatetime, '06/30/2012') as [ArchiveDate]
,EmployeeID
,EmployeeName
,StartDate
,EndDate
,Salary
,Position
,HomeAddress
FROM dbo.Employee2012Q2
GO
获取每位员工的最新信息
SELECT A.*
FROM dbo.EmployeeArchive A
JOIN (
SELECT EmployeeID, MAX(ArchiveDate) as MaxArchiveDate
FROM dbo.EmployeeArchive
GROUP BY EmployeeID
) B
ON A.EmployeeID = B.EmployeeID
AND A.ArchiveDate = B.MaxArchiveDate