我有2个表名为请假请求和请假详细信息,它包含如下数据
Leave Request
Leave_Req_Id|start_date | end_date |
------------+-----------+-----------+
lvl10001 | 2013-01-05| 2013-01-08|
| | |
Leave Request Detail
Req_Detail_Id |start_date | end_date | canceled |
--------------+-----------+------------+----------+-
lvl10001 | 2013-01-05| 2013-01-05 | no |
lvl10001 | 2013-01-06| 2013-01-06 | no |
lvl10001 | 2013-01-07| 2013-01-07 | yes |
lvl10001 | 2013-01-08| 2013-01-08 | no |
我想要的结果是排除取消的记录并将数据放入视图表中,如下所示
Report_Id |start_date | end_date |
--------------+-----------+------------+-
rep10001 | 2013-01-05| 2013-01-06 |
rep10002 | 2013-01-08| 2013-01-08 |
If the cancelled record starts from the front or back of the range, the
result should be like below
Eg. Cancelled on 2013-01-05 only
Report_Id |start_date | end_date |
--------------+-----------+------------+-
rep10001 | 2013-01-06| 2013-01-08 |
| | |
Eg. Cancelled on 2013-01-08 only
Report_Id |start_date | end_date |
--------------+-----------+------------+-
rep10001 | 2013-01-05| 2013-01-07 |
| | |
If there is no cancelled record, the result should be like below
Report_Id |start_date | end_date |
--------------+-----------+------------+-
rep10001 | 2013-01-05| 2013-01-08 |
| | |
当前结果(2018年6月19日)基于马扎尔的方法。 我修改了你的查询abit
查询:
WITH cteX
AS(
SELECT
Id = ROW_NUMBER()OVER(PARTITION BY D.request_no ORDER BY
D.leave_starttime ASC)
,a.leave_code
,a.emp_id
,D.request_no
,D.leave_starttime
,D.leave_endtime
,D.cancelsts
FROM TTADLEAVEREQUEST a
left join TTADLEAVEREQUESTDETAIL D on a.request_no = d.request_no
where a.emp_id = 'emp1' and Year(a.leave_startdate) =
2018
)
SELECT
ReportId = 'rep1000' + CAST(ROW_NUMBER()OVER(ORDER BY (SELECT NULL) ) AS
NVARCHAR(5))
,leave_starttime = MIN(Y.leave_starttime)
,leave_endtime = MAX(Y.leave_endtime)
,leave_code = Y.leave_code
,Count(Y.leave_starttime) as TOTAL_COUNT
FROM (
SELECT TOP 100 PERCENT
Grp = Id - ROW_NUMBER()OVER( PARTITION BY X.cancelsts ORDER BY X.Id)
,X.request_no
,X.leave_code
,X.leave_starttime
,X.leave_endtime
,X.cancelsts
FROM
cteX X
WHERE
X.cancelsts = 'n'
ORDER BY
X.emp_id
) Y
GROUP BY
Y.Grp,Y.leave_code
=============================================== ===========
LeaveRequest Table
request_no||leave_code||emp_id||leave_startdate ||leave_enddate ||
==================================================================
1001 || AL ||emp1 ||2018-01-29 00:00||2018-01-30 00:00
1002 || AL ||emp1 ||2018-02-01 00:00||2018-02-02 00:00
1003 || AL ||emp1 ||2018-02-12 00:00||2018-02-13 00:00
LeaveRequestDetail Table
request_no|| leave_starttime || leave_endtime || cancelsts
=====================================================
1001 || 2018-01-29 08:00 || 2018-01-29 17:00 || N
1001 || 2018-01-30 08:00 || 2018-01-30 17:00 || N
1002 || 2018-02-01 08:00 || 2018-02-01 17:00 || N
1002 || 2018-02-02 08:00 || 2018-02-02 17:00 || N
1003 || 2018-02-12 08:00 || 2018-02-12 17:00 || N
1003 || 2018-02-13 08:00 || 2018-02-13 17:00 || N
此查询的结果:
Result Table
ReportID || leave_starttime || leave_endtime || leave_code || TOTAL_COUNT
======================================================================
rep10001 || 2018-01-30 || 2018-01-30 || AL || 1
rep10002 || 2018-02-02 || 2018-02-02 || AL || 1
rep10003 || 2018-02-12 || 2018-02-13 || AL || 2
rep10004 || 2018-02-01 || 2018-02-01 || AL || 1
rep10005 || 2018-01-29 || 2018-01-29 || AL || 1
正如您所看到的,结果应该只有3行(例如,1月29日和1月30日以及2月1日和2月02日应该是单一记录)。真的很感激你可以提供帮助。感谢。
答案 0 :(得分:0)
一种方法是使用row_numbers
select replace(min(rd.Req_Detail_Id), 'det', 'rep') as Report_Id,
min(rd.start_date) as start_date, max(rd.end_date) as end_date
from (
select *,
row_number() over (order by Req_Detail_Id) Seq1,
row_number() over (partition by Leave_Req_Id, canceled order by Req_Detail_Id) Seq2
from LeaveRequest r
inner join LeaveRequestDetail rd on rd.Leave_Req_Id = r.Leave_Req_Id
where rd.canceled = 'no'
) t
group by (Seq1-Seq2);
答案 1 :(得分:0)
尝试以下脚本 样本数据
DECLARE @LeaveRequest AS TABLE (Leave_Req_Id varchar(100),[start_date] DATE , end_date DATE)
INSERT INTO @LeaveRequest
SELECT 'lvl10001' , '2013-01-05', '2013-01-08'
DECLARE @LeaveRequestDetail AS TABLE(Req_Detail_Id varchar(100) ,[start_date] DATE, end_date DATE , canceled varchar(5), Leave_Req_Id varchar(100))
INSERT INTO @LeaveRequestDetail
SELECT 'det10001' , '2013-01-05', '2013-01-05' ,'no' , 'lvl10001' UNION All
SELECT 'det10002' , '2013-01-06', '2013-01-06' ,'no' , 'lvl10001' UNION All
SELECT 'det10003' , '2013-01-07', '2013-01-07' ,'yes', 'lvl10001' UNION All
SELECT 'det10004' , '2013-01-08', '2013-01-08' ,'no' , 'lvl10001'
Sql脚本
;WITH CTE
AS
(
SELECT Req_Detail_Id,
[start_date],
CASE WHEN canceled = 'NO' THEN LEAD(end_date,1)OVER(ORDER BY Req_Detail_Id)
ELSE end_date END end_date
FROM
(
SELECT d.Req_Detail_Id,
d.[start_date],
d.end_date,
d.canceled
FROM @LeaveRequest l
INNER JOIN @LeaveRequestDetail d
ON d.Leave_Req_Id=l.Leave_Req_Id
WHERE d.[start_date]>=l.[start_date]
AND d.end_date <=l.end_date
AND d.canceled <>'Yes'
)dt
)SELECT REPLACE(Req_Detail_Id,'det','rep') AS Report_Id ,
[start_date],
end_date
FROM CTE
WHERE end_date IS NOT NULL
演示结果http://rextester.com/XVVG52381
Report_Id start_date end_date
----------------------------------
rep10001 2013-01-05 2013-01-06
rep10002 2013-01-06 2013-01-08
答案 2 :(得分:0)
这是一个差距和群岛问题。
测试数据 - 注意在正面和背面取消1001和1003
CREATE TABLE LeaveRequest
([request_no] int, [leave_code] varchar(2), [emp_id] varchar(4), [leave_startdate] datetime, [leave_enddate] datetime)
;
INSERT INTO LeaveRequest
([request_no], [leave_code], [emp_id], [leave_startdate], [leave_enddate])
VALUES
(1001, 'AL', 'emp1', '2018-01-28 00:00:00', '2018-01-30 00:00:00'),
(1002, 'AL', 'emp1', '2018-02-01 00:00:00', '2018-02-02 00:00:00'),
(1003, 'AL', 'emp1', '2018-02-12 00:00:00', '2018-02-14 00:00:00')
;
CREATE TABLE LeaveRequestDetail
([request_no] int, [leave_starttime] datetime, [leave_endtime] datetime, [cancelsts] varchar(1))
;
INSERT INTO LeaveRequestDetail
([request_no], [leave_starttime], [leave_endtime], [cancelsts])
VALUES
(1001, '2018-01-28 08:00:00', '2018-01-28 17:00:00', 'Y'),
(1001, '2018-01-29 08:00:00', '2018-01-29 17:00:00', 'N'),
(1001, '2018-01-30 08:00:00', '2018-01-30 17:00:00', 'N'),
(1002, '2018-02-01 08:00:00', '2018-02-01 17:00:00', 'N'),
(1002, '2018-02-02 08:00:00', '2018-02-02 17:00:00', 'N'),
(1003, '2018-02-12 08:00:00', '2018-02-12 17:00:00', 'N'),
(1003, '2018-02-13 08:00:00', '2018-02-13 17:00:00', 'N'),
(1003, '2018-02-14 08:00:00', '2018-02-14 17:00:00', 'Y')
;
我通过使用递增ID并将其与ROW_NUMBER窗口函数相结合来处理类似的情况 - 注意对ROW_NUMBER函数的更改
;WITH cteX
AS(
SELECT
Id = ROW_NUMBER()OVER(ORDER BY D.request_no, D.leave_starttime ASC)
,D.request_no
,a.leave_code
,a.emp_id
,D.leave_starttime
,D.leave_endtime
,D.cancelsts
FROM LeaveRequest a
left join LeaveRequestDetail D on a.request_no = d.request_no
where a.emp_id = 'emp1' and Year(a.leave_startdate) = 2018
)
SELECT TOP 100 PERCENT
Grp = Id - ROW_NUMBER()OVER( PARTITION BY X.request_no, X.cancelsts ORDER BY X.Id)
,X.request_no
,X.leave_code
,X.leave_starttime
,X.leave_endtime
,X.cancelsts
FROM
cteX X
WHERE
X.cancelsts = 'n'
ORDER BY
X.request_no,X.emp_id
这给出了这个结果集,请注意Grp列
Grp request_no leave_code leave_starttime leave_endtime cancelsts
1 1001 AL 2018-01-29 08:00:00.000 2018-01-29 17:00:00.000 N
1 1001 AL 2018-01-30 08:00:00.000 2018-01-30 17:00:00.000 N
3 1002 AL 2018-02-01 08:00:00.000 2018-02-01 17:00:00.000 N
3 1002 AL 2018-02-02 08:00:00.000 2018-02-02 17:00:00.000 N
5 1003 AL 2018-02-12 08:00:00.000 2018-02-12 17:00:00.000 N
5 1003 AL 2018-02-13 08:00:00.000 2018-02-13 17:00:00.000 N
然后与CTE或派生表结合,您可以获得预期的输出
;WITH cteX
AS(
SELECT
Id = ROW_NUMBER()OVER(ORDER BY D.request_no, D.leave_starttime ASC)
,a.leave_code
,a.emp_id
,D.request_no
,D.leave_starttime
,D.leave_endtime
,D.cancelsts
FROM LeaveRequest a
left join LeaveRequestDetail D on a.request_no = d.request_no
where a.emp_id = 'emp1' and Year(a.leave_startdate) = 2018
)
SELECT
ReportId = 'rep1000' + CAST(ROW_NUMBER()OVER(ORDER BY (SELECT NULL) ) AS NVARCHAR(5))
,leave_starttime = MIN(Y.leave_starttime)
,leave_endtime = MAX(Y.leave_endtime)
,leave_code = Y.leave_code
,Count(Y.leave_starttime) as TOTAL_COUNT
FROM
(
SELECT TOP 100 PERCENT
Grp = Id - ROW_NUMBER()OVER( PARTITION BY X.request_no, X.cancelsts ORDER BY X.Id)
,X.request_no
,X.leave_code
,X.leave_starttime
,X.leave_endtime
,X.cancelsts
FROM
cteX X
WHERE
X.cancelsts = 'n'
ORDER BY
X.request_no,X.emp_id
) Y
GROUP BY
Y.Grp,Y.leave_code
输出
ReportId leave_starttime leave_endtime leave_code TOTAL_COUNT
rep10001 2018-01-29 08:00:00.000 2018-01-30 17:00:00.000 AL 2
rep10002 2018-02-01 08:00:00.000 2018-02-02 17:00:00.000 AL 2
rep10003 2018-02-12 08:00:00.000 2018-02-13 17:00:00.000 AL 2
答案 3 :(得分:0)
CREATE table #result (Report_id VARCHAR(50), [start_date] DATE, [end_date] DATE)
DECLARE
@st VARCHAR(20),
@en DATE,
@can VARCHAR(5),
@id_re VARCHAR(20),
@lenght INT ,
@id VARCHAR(20)
DECLARE find_records CURSOR FOR
SELECT
start_date,
end_date ,
canceled,
Leave_Req_Id
FROM [Leave Request Detail]
OPEN find_records
FETCH NEXT FROM find_records INTO @st, @en, @can, @id_re
WHILE @@fetch_status <> -1
BEGIN
SET @lenght = (LEN((SELECT MAX(Report_id) FROM #result))-3)
SET @id = RIGHT((SELECT MAX(Report_id) FROM #result), @lenght)
IF @can ='yes'
BEGIN
INSERT INTO #result
(
Report_id,
start_date,
end_date
)
VALUES
(
CASE WHEN @lenght IS NULL THEN 'rep10001'
ELSE 'rep'+ CAST((CAST(@id AS INT) + 1) AS VARCHAR(10)) END,
(SELECT MIN(start_date) FROM [Leave Request Detail] WHERE start_date <=@st and canceled='no' and Leave_Req_Id=@id_re),
@en
)
END
FETCH NEXT FROM find_records INTO @st, @en, @can, @id_re
END
CLOSE find_records
DEALLOCATE find_records
DECLARE missing_resords CURSOR FOR
SELECT
start_date,
end_date ,
canceled,
Leave_Req_Id
FROM [Leave Request Detail]
WHERE canceled != 'yes'
OPEN missing_resords
FETCH NEXT FROM missing_resords INTO @st, @en, @can, @id_re
WHILE @@fetch_status <> -1
BEGIN
SET @lenght = (LEN((SELECT MAX(Report_id) FROM #result))-3)
IF (@st> (SELECT MIN(end_date) from #result))
BEGIN
INSERT INTO #result
(
Report_id,
start_date,
end_date
)
VALUES
(
CASE WHEN @lenght IS NULL THEN 'rep10001'
ELSE 'rep'+ CAST((CAST(@id AS INT) + 1) AS VARCHAR(10)) END,
@st,
@en
)
END
FETCH NEXT FROM missing_resords INTO @st, @en, @can, @id_re
END
CLOSE missing_resords
DEALLOCATE missing_resords
select * from #result