我有一个存储EmployeeId, TourMonth, StartMonth, EndMonth
的表。
TourMonth
代表月份,1
代表1月,2
代表2月等。
我想从此表中找到给定startdate
和enddate
之间的缺失月份。以下为1月至12月的员工3071的示例,缺少2月,4月,7月,9月。如何从表格中获得结果?
EmployeeId TourMonth StartMonth EndMonth
--------- --------- --------- --------
3071 1 2015-01-13 00:00:00.000 2015-01-14 00:00:00.000
3071 3 2015-03-15 00:00:00.000 2015-04-15 00:00:00.000
3071 5 2015-05-15 00:00:00.000 2015-06-15 00:00:00.000
3071 6 2015-06-15 00:00:00.000 2015-07-15 00:00:00.000
3071 8 2015-08-15 00:00:00.000 2015-09-15 00:00:00.000
3071 10 2015-10-15 00:00:00.000 2015-11-15 00:00:00.000
我想要的输出:
如果我传入startdate = 2015-01-01
和enddate = 2015-11-01
以及EmployeeId = 3071
,那么我应该得到:
EmployeeId MissingMonth
----------- ------------
3071 February
3071 April
3071 July
3071 September
答案 0 :(得分:1)
使make代码更直接,创建具有月份名称的表:
IF EXISTS (SELECT * FROM sys.all_objects WHERE object_id = OBJECT_ID('[dbo].[tbl_Months]') AND type IN ('U'))
DROP TABLE [dbo].[tbl_Months]
GO
CREATE TABLE [dbo].[tbl_Months] (
[id] int NULL,
[month] varchar(20) COLLATE Latin1_General_CI_AS NULL
)
ON [PRIMARY]
GO
-- ----------------------------
-- Records of tbl_Months
-- ----------------------------
BEGIN TRANSACTION
GO
INSERT INTO [dbo].[tbl_Months] VALUES ('1', 'January');
INSERT INTO [dbo].[tbl_Months] VALUES ('2', 'February');
INSERT INTO [dbo].[tbl_Months] VALUES ('3', 'March');
INSERT INTO [dbo].[tbl_Months] VALUES ('4', 'April');
INSERT INTO [dbo].[tbl_Months] VALUES ('5', 'May');
INSERT INTO [dbo].[tbl_Months] VALUES ('6', 'June');
INSERT INTO [dbo].[tbl_Months] VALUES ('7', 'July');
INSERT INTO [dbo].[tbl_Months] VALUES ('8', 'August');
INSERT INTO [dbo].[tbl_Months] VALUES ('9', 'September');
INSERT INTO [dbo].[tbl_Months] VALUES ('10', 'October');
INSERT INTO [dbo].[tbl_Months] VALUES ('11', 'November');
INSERT INTO [dbo].[tbl_Months] VALUES ('12', 'December');
GO
COMMIT
然后简单选择:
SELECT [id], [month] from tbl_Months
WHERE NOT EXISTS (SELECT TourMonth FROM table_name WHERE "some conditions")
我没有解释某些条件,因为它可能有很多变种
答案 1 :(得分:0)
您可以内联注入1-12个月的行,但您可能会发现物理date table非常有用。
下面是一个简单的内联示例:
declare @EmployeeTours table (EmployeeId int, TourMonth int, StartMonth datetime, EndMonth datetime);
insert into @EmployeeTours
values
(3071, 1, '2015-01-13 00:00:00.000', '2015-01-14 00:00:00.000'),
(3071, 3, '2015-03-15 00:00:00.000', '2015-04-15 00:00:00.000'),
(3071, 5, '2015-05-15 00:00:00.000', '2015-06-15 00:00:00.000'),
(3071, 6, '2015-06-15 00:00:00.000', '2015-07-15 00:00:00.000'),
(3071, 8, '2015-08-15 00:00:00.000', '2015-09-15 00:00:00.000'),
(3071, 10, '2015-10-15 00:00:00.000', '2015-11-15 00:00:00.000')
declare @EmployeeId int = 3071,
@StartMonth datetime = '2015-01-01',
@EndMonth datetime = '2015-11-01';
select @EmployeeId, datename(month, dateadd(month, d.TourMonth, 0)-1)
from (values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12))d(TourMonth)
left
join @EmployeeTours et on
d.TourMonth = et.TourMonth and
StartMonth >= @StartMonth and
EndMonth <= @EndMonth and
EmployeeId = @EmployeeId
where et.EmployeeId is null
group
by EmployeeId, d.TourMonth
返回:
3071 February
3071 April
3071 July
3071 September
3071 October
3071 November
3071 December