我有一个SQL表,显示员工的出勤情况,如日期,时间,员工ID和密钥(进出),如下:
ID AttTime Key attDate
123 08:00 AM IN 2015-08-21
123 06:00 PM OUT 2015-08-21
123 08:00 AM IN 2015-08-22
123 06:00 PM OUT 2015-08-22
123 08:00 AM IN 2015-08-23
123 06:00 PM OUT 2015-08-23
123 08:00 AM IN 2015-08-24
123 06:00 PM OUT 2015-08-24
123 08:00 AM IN 2015-08-25
123 06:00 PM OUT 2015-08-25
123 08:00 AM IN 2015-08-26
123 06:00 PM OUT 2015-08-26
123 08:00 AM IN 2015-08-27
123 06:00 PM OUT 2015-08-27
现在我想显示所有请求的日期,即使他们没有任何数据.. 例如:如果用户请求2015年8月1日至2015年8月30日的报告 我希望输出如下:
ID AttTime Key attDate
null null null 2015-08-01
null null null 2015-08-01
null null null 2015-08-02
null null null 2015-08-02
null null null 2015-08-03
null null null 2015-08-03
null null null 2015-08-04
null null null 2015-08-04
.
.
.
.
.
123 08:00 AM IN 2015-08-21
123 06:00 PM OUT 2015-08-21
123 08:00 AM IN 2015-08-22
123 06:00 PM OUT 2015-08-22
123 08:00 AM IN 2015-08-23
123 06:00 PM OUT 2015-08-23
123 08:00 AM IN 2015-08-24
123 06:00 PM OUT 2015-08-24
123 08:00 AM IN 2015-08-25
123 06:00 PM OUT 2015-08-25
123 08:00 AM IN 2015-08-26
123 06:00 PM OUT 2015-08-26
123 08:00 AM IN 2015-08-27
123 06:00 PM OUT 2015-08-27
null null null 2015-08-28
null null null 2015-08-28
null null null 2015-08-29
null null null 2015-08-29
null null null 2015-08-30
null null null 2015-08-30
如何制作?
答案 0 :(得分:0)
这是一个创建日期范围表的解决方案,并为缺失的日期执行memset()
:
RIGHT JOIN
如果您还要为缺失日期的Declare @StartDate Date = '2015-08-01',
@EndDate Date = '2015-08-30'
;With Date (Date) As
(
Select @StartDate Union All
Select DateAdd(Day, 1, Date)
From Date
Where Date < @EndDate
),
Keys As
(
Select 'IN' As [Key]
Union All
Select 'OUT' As [Key]
),
InOutDates As
(
Select Date, [Key]
From Date
Cross Join Keys
)
Select E.ID, E.AttTime, E.[Key], D.Date As attDate
From EmployeeTable E
Right Join InOutDates D On D.Date = E.AttDate
And E.[Key] = D.[Key]
Option (MaxRecursion 0)
选择IN
/ OUT
值,您可以使用:
Key
这是一个SQLFiddle演示。
答案 1 :(得分:0)
这就是你需要的:
Declare @start date = '20150801';
Declare @end date = '20150830';
With inc(n) as (
Select TOP(1+DATEDIFF(day, @start, @end)) ROW_NUMBER() over(order by (select 1))-1
From (
Select 1 From (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as x1(n)
Cross Join (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as x2(n)
) as x(n)
)
Select d.ID, d.AttTime, d.key, attDate = DATEADD(day, n, @start)
From inc
Cross Join (values('IN'), ('OUT')) as k(name)
Left Join yourData as d on d.attDate = DATEADD(day, n, @start) and d.key = k.name;
CTE inc在不使用递归CTE的情况下创建从0到n的数字(@start和@end之间的差异,以天为单位)。 然后使用IN和OUT交叉加入所有数字,并使用IN / OUT创建一系列日期。 它最后左边用你的数据加入这个范围
答案 2 :(得分:-3)
如果我找对你,所有元组都可用,你只想执行一个范围查询,对吗?
你有没有试过像:
def home(request, var1):
#...