我希望获得在给定日期范围内存在/不存在的所有用户。
CREATE TABLE [tt](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [varchar](20) NULL,
[EmpCode] [varchar](50) NULL,
[Name] [varchar](200) NULL,
[WorkDate] [varchar](20) NULL,
[InTime] [varchar](20) NULL,
[OutTime] [varchar](20) NULL,
[TotalTime] [varchar](50) NULL,
)
insert into [tt] values
('106','E2E106','Goutam Kumar','2017-02-21','12:54:54 PM','10:06:42 PM','08:55:00')
,('106','E2E106','Goutam Kumar','2017-02-20','12:49:21 PM','09:26:27 PM','07:53:00')
,('106','E2E106','Goutam Kumar','2017-02-15','12:31:51 PM','09:21:14 PM','08:30:00')
,('106','E2E106','Goutam Kumar','2017-02-13','05:46:06 PM','09:32:17 PM','03:46:00')
,('106','E2E106','Goutam Kumar','2017-02-14','01:02:28 PM','09:32:50 PM','07:39:00')
,('111','E2E111','Mansi Manchanda','2017-02-21','12:42:42 PM','09:09:42 PM','08:07:00')
,('111','E2E111','Mansi Manchanda','2017-02-17','12:09:11 PM','09:40:46 PM','06:36:00')
,('111','E2E111','Mansi Manchanda','2017-02-16','11:56:21 AM','09:20:08 PM','08:07:00')
,('111','E2E111','Mansi Manchanda','2017-02-15','01:07:19 PM','09:57:40 PM','08:30:00')
CREATE TABLE tUserInfo(
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [nvarchar](20) NULL,
[Name] [nvarchar](200) NULL,
[EmpCode] [varchar](200) NULL,
)
INSERT into tUserInfo VALUES
('106','Goutam Kumar','E2E106')
,('111','Mansi Manchanda','E2E111')
,('112','Arvind Kumar Prajapati','E2E112')
,('116','Rahul Garg','E2E116')
我能够获得给定日期的用户的现状/缺席状态。 但我的问题是,我希望获得在给定日期范围内存在/不存在的所有用户。
我希望数据看起来像这样:
Id UserId Name EmpCode InTime OutTime WorkDate Status
1 106 Goutam Kumar E2E106 2017-02-13 Present
2 111 Mansi Manchanda E2E111 2017-02-14 Absent
3 112 Arvind Kumar E2E112 2017-02-14 Absent
4 116 Rahul Garg E2E116 2017-02-17 Absent
答案 0 :(得分:3)
rextester:http://rextester.com/LCUT68753
使用outer apply()
和case
表达式显示所有用户,并且缺席整个时间或至少出现一次:
declare @fromdate date = '20170201'
declare @thrudate date = '20170214'
select u.*
, Status=case when x.WorkDate is null then 'Absent' else 'Present' end
from tUserInfo as u
outer apply (
select top 1 tt.WorkDate
from tt
where tt.UserId = u.UserId
and tt.WorkDate >= @fromdate
and tt.WorkDate <= @thrudate
) as x
返回:
+----+--------+------------------------+---------+---------+
| Id | UserId | Name | EmpCode | Status |
+----+--------+------------------------+---------+---------+
| 1 | 106 | Goutam Kumar | E2E106 | Present |
| 2 | 111 | Mansi Manchanda | E2E111 | Absent |
| 3 | 112 | Arvind Kumar Prajapati | E2E112 | Absent |
| 4 | 116 | Rahul Garg | E2E116 | Absent |
+----+--------+------------------------+---------+---------+
使用not exists()
<:p>的用户缺席整个持续时间
select *
from tUserInfo as u
where not exists (
select 1
from tt
where tt.UserId = u.UserId
and tt.WorkDate >= @fromdate
and tt.WorkDate <= @thrudate
)
返回:
+----+--------+------------------------+---------+
| Id | UserId | Name | EmpCode |
+----+--------+------------------------+---------+
| 2 | 111 | Mansi Manchanda | E2E111 |
| 3 | 112 | Arvind Kumar Prajapati | E2E112 |
| 4 | 116 | Rahul Garg | E2E116 |
+----+--------+------------------------+---------+
所有用户至少使用exists()
:
select *
from tUserInfo as u
where exists (
select 1
from tt
where tt.UserId = u.UserId
and tt.WorkDate >= @fromdate
and tt.WorkDate <= @thrudate
)
返回:
+----+--------+--------------+---------+
| Id | UserId | Name | EmpCode |
+----+--------+--------------+---------+
| 1 | 106 | Goutam Kumar | E2E106 |
+----+--------+--------------+---------+
要知道在日期范围内每个workdate
缺席的人和谁在场:
select
u.UserId
, u.Name
, d.WorkDate
, [Status] = case when x.WorkDate is null then 'Absent' else 'Present' end
from (select distinct UserId, Name from tUserInfo) as u
cross join (
select distinct
WorkDate
from tt
where tt.WorkDate >= @fromdate
and tt.WorkDate <= @thrudate
) as d
outer apply (
select top 1 tt.WorkDate
from tt
where tt.UserId = u.UserId
and tt.WorkDate = d.WorkDate
) as x
返回:
+--------+------------------------+------------+---------+
| UserId | Name | WorkDate | Status |
+--------+------------------------+------------+---------+
| 106 | Goutam Kumar | 2017-02-13 | Present |
| 111 | Mansi Manchanda | 2017-02-13 | Absent |
| 112 | Arvind Kumar Prajapati | 2017-02-13 | Absent |
| 116 | Rahul Garg | 2017-02-13 | Absent |
| 106 | Goutam Kumar | 2017-02-14 | Present |
| 111 | Mansi Manchanda | 2017-02-14 | Absent |
| 112 | Arvind Kumar Prajapati | 2017-02-14 | Absent |
| 116 | Rahul Garg | 2017-02-14 | Absent |
+--------+------------------------+------------+---------+
注意:这仅检查表workdate
中存在的tt
。
如果您还需要检查指定日期范围内tt
内不存在的日期,可以使用common table expression生成日期范围的日期:
set @fromdate = '20170212'
set @thrudate = '20170214'
;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, dates as (
select top (datediff(day, @fromdate, @thrudate)+1)
[Date]=convert(date,dateadd(day
, row_number() over (order by (select 1)) -1, @fromdate))
from n as deka
cross join n as hecto /* 100 days */
--cross join n as kilo /* 2.73 years */
--cross join n as [tenK] /* 27.3 years */
order by [Date]
)
select
u.UserId
, u.Name
, WorkDate = convert(varchar(10),d.Date,120)
, [Status] = case when x.WorkDate is null then 'Absent' else 'Present' end
from (select distinct UserId, Name from tUserInfo) as u
cross join dates as d
outer apply (
select top 1 tt.WorkDate
from tt
where tt.UserId = u.UserId
and tt.WorkDate = d.Date
) as x
返回:
+--------+------------------------+------------+---------+
| UserId | Name | WorkDate | Status |
+--------+------------------------+------------+---------+
| 106 | Goutam Kumar | 2017-02-12 | Absent |
| 111 | Mansi Manchanda | 2017-02-12 | Absent |
| 112 | Arvind Kumar Prajapati | 2017-02-12 | Absent |
| 116 | Rahul Garg | 2017-02-12 | Absent |
| 106 | Goutam Kumar | 2017-02-13 | Present |
| 111 | Mansi Manchanda | 2017-02-13 | Absent |
| 112 | Arvind Kumar Prajapati | 2017-02-13 | Absent |
| 116 | Rahul Garg | 2017-02-13 | Absent |
| 106 | Goutam Kumar | 2017-02-14 | Present |
| 111 | Mansi Manchanda | 2017-02-14 | Absent |
| 112 | Arvind Kumar Prajapati | 2017-02-14 | Absent |
| 116 | Rahul Garg | 2017-02-14 | Absent |
+--------+------------------------+------------+---------+
答案 1 :(得分:0)
使用pivot概念并获取所有日期,然后分别放置用户
DECLARE @cols AS NVARCHAR(MAX)
DECLARE @query AS NVARCHAR(MAX)
SET @cols=STUFF((SELECT distinct ',' + QUOTENAME(c.WorkDate)
FROM tt c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT Id,UserId,EmpCode, ' + @cols + ' from
(
select Id
, UserId
, EmpCode
,Name
,WorkDate
from tt
) x
pivot
(
max(Name)
for WorkDate in (' + @cols + ')
) p '
execute(@query)