Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 我看不出显示没有员工id的日期有什么意义。这不会告诉你哪个员工缺席。。。另外,3个表的结构可能应该是一个表,但那是另一回事。@ZoharPeled,事实上,缺席日期没有员工id,所以我们只需要获取那些没有任何员工数据的日期。只有员工在场的日期,我们需要首先_Sql Server_Tsql_Sql Server 2012 - Fatal编程技术网

Sql server 我看不出显示没有员工id的日期有什么意义。这不会告诉你哪个员工缺席。。。另外,3个表的结构可能应该是一个表,但那是另一回事。@ZoharPeled,事实上,缺席日期没有员工id,所以我们只需要获取那些没有任何员工数据的日期。只有员工在场的日期,我们需要首先

Sql server 我看不出显示没有员工id的日期有什么意义。这不会告诉你哪个员工缺席。。。另外,3个表的结构可能应该是一个表,但那是另一回事。@ZoharPeled,事实上,缺席日期没有员工id,所以我们只需要获取那些没有任何员工数据的日期。只有员工在场的日期,我们需要首先,sql-server,tsql,sql-server-2012,Sql Server,Tsql,Sql Server 2012,我看不出显示没有员工id的日期有什么意义。这不会告诉你哪个员工缺席。。。另外,3个表的结构可能应该是一个表,但那是另一回事。@ZoharPeled,事实上,缺席日期没有员工id,所以我们只需要获取那些没有任何员工数据的日期。只有员工在场的日期,我们需要首先获取每个表的MIN(ColDate)和MAX(ColDate)之间的所有日期,并找出缺少的日期。如果我仍然无法描述的话,我很抱歉。但是,对不起,你是想获取三明治信息吗。比如假期前后缺勤,这会成为假日的三明治吗?这是您想要的输出吗?很好,您已经将


我看不出显示没有员工id的日期有什么意义。这不会告诉你哪个员工缺席。。。另外,3个表的结构可能应该是一个表,但那是另一回事。@ZoharPeled,事实上,缺席日期没有员工id,所以我们只需要获取那些没有任何员工数据的日期。只有员工在场的日期,我们需要首先获取每个表的
MIN(ColDate)
MAX(ColDate)
之间的所有日期,并找出缺少的日期。如果我仍然无法描述的话,我很抱歉。但是,对不起,你是想获取三明治信息吗。比如假期前后缺勤,这会成为假日的三明治吗?这是您想要的输出吗?很好,您已经将示例数据发布为DDL+DML,但您的问题仍然不是很清楚。@ZoharPeled,我想显示员工数据及其当前和不存在的日期。如果员工连续缺勤超过一天,则应显示
FromDate to ToDate
,并显示
null EmpID
。并且还想用
empID
显示当前日期前后的一天。很抱歉,我看不出显示没有员工id的日期有什么意义。这并不能告诉您哪个员工缺席。。。另外,3个表的结构可能应该是一个表,但那是另一回事。@ZoharPeled,事实上,缺席日期没有员工id,所以我们只需要获取那些没有任何员工数据的日期。只有员工在场的日期,我们需要首先获取每个表的
MIN(ColDate)
MAX(ColDate)
之间的所有日期,并找出缺少的日期。如果我仍然无法描述的话,我很抱歉。但是,对不起,你是想获取三明治信息吗。比如假期前后缺勤,这会成为假日的三明治吗?这是您想要的输出吗?我们是否可以更改此查询以获得2、3、4或n个日前和日后数字。当前查询返回数据前后的1个日期。请参阅
LAG()
LEAD()
上的文档。使用
offset
参数获取所需的
n
数字。我们可以更改此查询以获取日前和日后的2、3、4或n个数字。当前查询返回数据前后的1个日期。请参阅
LAG()
LEAD()
上的文档。使用
offset
参数获取所需的
n
编号
--Table 1:
CREATE TABLE tbl_Emp_1
(
    EmpID INT,
    ColDate DATE
);

INSERT INTO tbl_Emp_1 VALUES(1,'2019-11-01');
INSERT INTO tbl_Emp_1 VALUES(2,'2019-11-02');
INSERT INTO tbl_Emp_1 VALUES(3,'2019-11-11');
INSERT INTO tbl_Emp_1 VALUES(4,'2019-11-12');
INSERT INTO tbl_Emp_1 VALUES(9,'2019-11-13');
INSERT INTO tbl_Emp_1 VALUES(6,'2019-11-16');
INSERT INTO tbl_Emp_1 VALUES(408,'2019-11-25');

--Table 2:
CREATE TABLE tbl_Emp_2
(
    EmpID INT,
    ColDate DATE
);

INSERT INTO tbl_Emp_2 VALUES(11,'2019-11-02');
INSERT INTO tbl_Emp_2 VALUES(22,'2019-11-06');
INSERT INTO tbl_Emp_2 VALUES(22,'2019-11-08');
INSERT INTO tbl_Emp_2 VALUES(33,'2019-11-10');
INSERT INTO tbl_Emp_2 VALUES(44,'2019-11-15');

--Table 3:
CREATE TABLE tbl_Emp_3
(
    EmpID INT,
    ColDate DATE
);

INSERT INTO tbl_Emp_3 VALUES(111,'2019-11-12');
INSERT INTO tbl_Emp_3 VALUES(222,'2019-11-16');
INSERT INTO tbl_Emp_3 VALUES(333,'2019-11-17');
INSERT INTO tbl_Emp_3 VALUES(444,'2019-11-19');
INSERT INTO tbl_Emp_3 VALUES(5,'2019-11-22');
CREATE VIEW vw_Emp AS
SELECT *,1 AS TableID FROM tbl_Emp_1
UNION ALL
SELECT *,2 AS TableID FROM tbl_Emp_2
UNION ALL
SELECT *,3 AS TableID FROM tbl_Emp_3;
EmpID   ColDate     
--------------------------------
2       2019-11-02          ---TABLE 1 Starts
NULL    2019-11-03 - 2019-11-10
3       2019-11-11
9       2019-11-13
NULL    2019-11-14 - 2019-11-15
6       2019-11-16
NULL    2019-11-17 - 2019-11-24
408     2019-11-25
11      2019-11-02          ---TABLE 2 Data Starts
NULL    2019-11-03 - 2019-11-05
22      2019-11-06  
NULL    2019-11-07
22      2019-11-08
NULL    2019-11-09
33      2019-11-10
NULL    2019-11-11 - 2019-11-14
44      2019-11-15
111     2019-11-12      ---TABLE 3 Data Starts
NULL    2019-11-13 - 2019-11-15
222     2019-11-16 
333     2019-11-17
NULL    2019-11-18
444     2019-11-19  
NULL    2019-11-20 - 2019-11-21
5       2019-11-22
DECLARE @TableID INT,
        @MinDate DATE,
        @MaxDate DATE;
DECLARE Cur_Get_MinMax1 CURSOR FOR 
SELECT TableID,
       (SELECT MIN(ColDate) FROM vw_Emp WHERE TableID = v1.TableID),
       (SELECT MAX(ColDate) FROM vw_Emp WHERE TableID = v1.TableID)
FROM vw_Emp v1
GROUP BY TableID;

IF OBJECT_ID('tempdb..#TempEmpData') IS NOT NULL 
DROP TABLE #TempEmpData;

CREATE TABLE #TempEmpData
(
    Dates DATE,
    TableID int
);

OPEN Cur_Get_MinMax1;

FETCH NEXT FROM Cur_Get_MinMax1 INTO 
@TableID, 
@MinDate,
@MaxDate;

WHILE @@FETCH_STATUS = 0
BEGIN

    PRINT(@TableID);
    PRINT(@MinDate);
    PRINT(@MaxDate);

    INSERT INTO #TempEmpData 
    SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
            Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate),
            @TableID
    FROM sys.all_objects a
    CROSS JOIN sys.all_objects b

    FETCH NEXT FROM Cur_Get_MinMax1 INTO 
    @TableID, 
    @MinDate,
    @MaxDate;

END;
CLOSE Cur_Get_MinMax1;
DEALLOCATE Cur_Get_MinMax1;
SELECT v.EmpID,t.Dates
FROM #TempEmpData t 
LEFT JOIN vw_Emp v ON v.ColDate = t.Dates AND v.TableID = t.TableID
ORDER BY t.TableID,t.Dates;
;WITH CTE AS
(
    SELECT  DISTINCT TableID,Dates,EmpID,
            coalesce(stuff((select distinct CAST(MIN(Dates) as varchar(10))+'~'+ CAST(MAX(Dates) as varchar(10)) from #TempEmpData t1 where a.rr = 1 AND t1.Dates=a.Dates for xml path('')),1,0,''),cast(Dates as varchar(10))) Coldate
    FROM 
    (
        SELECT  v.EmpID, 
                t.Dates,
                t.TableID,
                RANK() OVER(ORDER BY v.EmpID) rr
        FROM vw_Emp v  
        RIGHT JOIN #TempEmpData t ON v.ColDate = t.Dates  AND v.TableID = t.TableID
        GROUP BY t.TableID,v.EmpID,t.Dates,v.TableID
    ) a
)
SELECT EmpID,ColDate 
FROM CTE
ORDER BY TableID,Dates
    SELECT CAST(NULL AS INT) AS EmpId, DATEADD(day, 1, PreviousDate) AS StartDate, DATEADD(day, -1, ColDate) AS EndDate
    FROM
    (
        SELECT ColDate, LAG(ColDate) OVER(ORDER BY ColDate) AS PreviousDate, LEAD(ColDate) OVER(ORDER BY ColDate) AS NextDate
        FROM (SELECT DISTINCT ColDate FROM dbo.tbl_Emp_1) AS src
    ) AS thedates
    WHERE ColDate <> DATEADD(day, 1, PreviousDate)



    SELECT CAST(NULL AS INT) AS EmpId, StartDate, EndDate
    FROM
    (
        SELECT DATEADD(day, 1, sd.StartDate) AS StartDate, DATEADD(day, -1, MIN(ed.EndDate)) AS EndDate
        FROM 
        (
            --start dates of missing ranges
            SELECT ColDate AS StartDate
            FROM dbo.tbl_Emp_1 as a
            WHERE NOT EXISTS(SELECT * FROM dbo.tbl_Emp_1 AS b WHERE b.ColDate = DATEADD(day, 1, a.ColDate))
        ) AS sd
        JOIN
        (
            --end dates of missing ranges
            SELECT ColDate AS EndDate
            FROM dbo.tbl_Emp_1 as a
            WHERE NOT EXISTS(SELECT * FROM dbo.tbl_Emp_1 AS b WHERE b.ColDate = DATEADD(day, -1, a.ColDate))
        ) AS ed ON sd.StartDate < ed.EndDate
        GROUP BY sd.StartDate
    ) AS emptyperiods
; with 
tbl_Emp as
(
    select  tbl = 1, EmpID, ColDate from tbl_Emp_1  
    union all
    select  tbl = 2, EmpID, ColDate from tbl_Emp_2  
    union all
    select  tbl = 3, EmpID, ColDate from tbl_Emp_3
),
cte as
(
    select  *,
            prevColDate = LAG(ColDate) over (partition by tbl order by ColDate),
            nextColDate = LEAD(ColDate) over (partition by tbl order by ColDate)
    from    tbl_Emp
)
-- first query
select  c.tbl, 
        c.EmpID, 
        c.ColDate, 
        EndDate     = NULL
from    cte c
where   c.ColDate   <> dateadd(day, +1, prevColDate)
or      c.ColDate   <> dateadd(day, -1, nextColDate)

union all

-- second query
select  c.tbl, 
        EmpID       = NULL,
        ColDate     = dateadd(day, 1, c.ColDate),
        EndDate     = dateadd(day, -1, nextColDate)
from    cte c
where   c.ColDate   <> dateadd(day, -1, nextColDate)

order by tbl, ColDate;