我有一个查询,它使用计数表插入指定月份的缺失行。查询测试该月中是否缺少某天,然后从列中获取不同的值(在该月中),并将这些值和缺少的日期值插入表中。
该表用于监控员工的工作日,时间以及他们工作的部分。问题是,如果工作人员移动部分,Section
列中的一个列Distinct
创建了两个特定日期的行集。
这会产生不良结果的查询,(@ Zohar Peled帮助我这样做)
DECLARE @startdt DATETIME = '2016/6/1';
DECLARE @enddt DATETIME = '2016/7/1';
DECLARE @value nvarchar(50);
DECLARE @T as TABLE
(
Staff_ID int,
[Date] date,
[Year] int,
Mon int,
[Day] int,
First_Name varchar(10),
Last_Name varchar(10),
Section varchar(10),
Time_Worked datetime
)
INSERT INTO @T VALUES
(1001, '2016-06-01', 2016, 6, 1, 'Bill', 'Price', 'Level 1', '2016-06-01 8:30:00.000'),
(1001, '2016-06-02', 2016, 6, 2, 'Bill', 'Price', 'Level 1', '2016-06-02 8:30:00.000'),
(1001, '2016-06-03', 2016, 6, 3, 'Bill', 'Price', 'Level 1', '2016-06-03 8:30:00.000'),
(1001, '2016-06-04', 2016, 6, 4, 'Bill', 'Price', 'Level 1', '2016-06-04 8:30:00.000'),
(1001, '2016-06-05', 2016, 6, 5, 'Bill', 'Price', 'Level 1', '2016-06-05 8:30:00.000'),
(1001, '2016-06-06', 2016, 6, 6, 'Bill', 'Price', 'Level 1', '2016-06-06 8:30:00.000'),
(1001, '2016-06-07', 2016, 6, 7, 'Bill', 'Price', 'Level 2', '2016-06-07 8:30:00.000'),-- Different section
(1001, '2016-07-05', 2016, 7, 5, 'Bill', 'Price', 'Level 2', '2016-07-5 8:30:00.000'),
(1002, '2016-06-01', 2016, 6, 1, 'Mary', 'Somers', 'Level 1', '2016-06-01 8:30:00.000'),
(1002, '2016-06-05', 2016, 6, 5, 'Mary', 'Somers', 'Level 1', '2016-06-05 8:30:00.000'),
(1002, '2016-06-08', 2016, 6, 8, 'Mary', 'Somers', 'Level 1', '2016-06-08 8:30:00.000'),
(1003, '2016-06-03', 2016, 6, 3, 'Mark', 'Jones', 'Level 1', '2016-06-03 8:30:00.000'),
(1003, '2016-06-04', 2016, 6, 4, 'Mark', 'Jones', 'Level 1', '2016-06-05 8:30:00.000')
--@value = SELECT Section_Data FROM Staff_Manager.dbo.Staff_Data_TBL WHERE Staff_No = 1001
SET NOCOUNT ON;
IF object_id('dbo.Tally') is not null drop table dbo.tally
SELECT TOP 30000 IDENTITY(int,1,1) as ID
INTO dbo.Tally FROM master.dbo.SysColumns
ALTER table dbo.Tally
add constraint PK_ID primary key clustered(ID)
; WITH Calendar AS
(
SELECT dateadd(DD, ID-1, @startdt) as [Date]
FROM dbo.Tally
WHERE dateadd(DD, ID-1, @startdt) < @enddt
)
INSERT INTO @T(Staff_ID, [Date], [Year], Mon, [Day], First_Name, Last_Name, Section)
SELECT DISTINCT Staff_ID, C.[Date], Year(C.[Date]), MONTH(C.[Date]), DAY(C.[Date]), First_Name, Last_Name, Section
FROM @T T
CROSS APPLY
(
SELECT Cal.[Date]
FROM Calendar Cal
WHERE MONTH(Cal.[Date]) = MONTH(T.[Date])
AND YEAR(Cal.[Date]) = YEAR(T.[Date])
AND NOT EXISTS
(
SELECT 1
FROM @T T2
WHERE T.Staff_ID = T2.Staff_ID
AND T2.[Date] = Cal.[Date]
)
) C
SELECT Staff_ID, [Date], [Year], Mon, [Day], First_Name, Last_Name, Section, Time_Worked
FROM @T
ORDER BY Staff_ID, [Date]
这是结果,正如您所看到的那样,由于Bill Price
从2016-06-08
更改Section
,工作人员Level 1
创建了两天到Level 2
。因为Distinct
语句将从Section
列中获得两个值。
(运行代码,你将获得所有结果,这只是一个表示我的意思的嗤之以鼻。)
Staff_ID Date Year Mon Day First_Name Last_Name Section Time_Worked
1001 2016-06-01 2016 6 1 Bill Price Level 1 2016-06-01 08:30:00.000
1001 2016-06-02 2016 6 2 Bill Price Level 1 2016-06-02 08:30:00.000
1001 2016-06-03 2016 6 3 Bill Price Level 1 2016-06-03 08:30:00.000
1001 2016-06-04 2016 6 4 Bill Price Level 1 2016-06-04 08:30:00.000
1001 2016-06-05 2016 6 5 Bill Price Level 1 2016-06-05 08:30:00.000
1001 2016-06-06 2016 6 6 Bill Price Level 1 2016-06-06 08:30:00.000
1001 2016-06-07 2016 6 7 Bill Price Level 2 2016-06-07 08:30:00.000
1001 2016-06-08 2016 6 8 Bill Price Level 1 NULL
1001 2016-06-08 2016 6 8 Bill Price Level 2 NULL
1001 2016-06-09 2016 6 9 Bill Price Level 1 NULL
1001 2016-06-09 2016 6 9 Bill Price Level 2 NULL
1001 2016-06-10 2016 6 10 Bill Price Level 1 NULL
1001 2016-06-10 2016 6 10 Bill Price Level 2 NULL
1001 2016-06-11 2016 6 11 Bill Price Level 1 NULL
1001 2016-06-11 2016 6 11 Bill Price Level 2 NULL
1001 2016-06-12 2016 6 12 Bill Price Level 1 NULL
1001 2016-06-12 2016 6 12 Bill Price Level 2 NULL
1001 2016-06-13 2016 6 13 Bill Price Level 1 NULL
1001 2016-06-13 2016 6 13 Bill Price Level 2 NULL
所以我有另一个表格,其中包含工作人员当前部分,请参阅下面的代码。
DECLARE @value nvarchar(50);
DECLARE @T3 as TABLE
(
Staff_ID int,
First_Name varchar(10),
Last_Name varchar(10),
Section varchar(10)
)
INSERT INTO @T3 VALUES
(1001, 'Bill', 'Price', 'Level 2'),
(1002, 'Mary', 'Somers', 'Level 1'),
(1003, 'Mark', 'Jones', 'Level 1')
SELECT Section FROM @T3 WHERE Staff_ID = 1001
结果如下,获取该工作人员的Section
数据。
Level 2
现在,如果我可以获取此值并将其用作Section
列中的默认值,以解决我的问题。
此代码显然不正确,但不是获取distinct
列的Section
值,而是将该值替换为另一个表@T3
中的值,
像这样的东西,
@value = SELECT Section FROM @T3 WHERE Staff_ID = 1001
然后将该值插入新行。
DECLARE @value nvarchar(50);
@value = SELECT Section FROM @T3 WHERE Staff_ID = 1001
INSERT INTO @T(Staff_ID, [Date], [Year], Mon, [Day], First_Name, Last_Name, Section)
SELECT DISTINCT Staff_ID, C.[Date], Year(C.[Date]), MONTH(C.[Date]), DAY(C.[Date]), First_Name, Last_Name, @value
FROM @T T
CROSS APPLY
(
SELECT Cal.[Date]
FROM Calendar Cal
WHERE MONTH(Cal.[Date]) = MONTH(T.[Date])
AND YEAR(Cal.[Date]) = YEAR(T.[Date])
AND Section = @value
AND NOT EXISTS
(
SELECT 1
FROM @T T2
WHERE T.Staff_ID = T2.Staff_ID
AND T2.[Date] = Cal.[Date]
)
) C
非常感谢任何帮助。
答案 0 :(得分:1)
查看代码中的评论
java.io.IOException
如果在OUTER APPLY中找不到任何记录,并且您想显示currenct部分,请加入@ T3并从那里获取该部分