识别日期范围内的记录差距
Identify Gaps of Records in Date Range
问题:我想确定哪些记录每天没有两条记录。 Rank 告诉我每天是否有第二条记录....
SELECT TR.tourid,
TR.tourruntimestamp,
TC.tourname,
TC.tourfrequency,
TC.unit,
TC.division,
RANK()
OVER (
PARTITION BY TR.tourid
ORDER BY TR.tourruntimestamp) AS [Rank]
FROM DBO.tbltourrun AS TR
INNER JOIN DBO.tso_piml_tour_config AS TC
ON TC.tourid = TR.tourid
WHERE ( TC.tourfrequency = '2xDay' )
AND ( TR.tourruntimestamp BETWEEN Dateadd(DAY, Datediff(DAY, 0, Getdate()) - 1, 0) AND Dateadd(DAY, Datediff(DAY, 0, Getdate()), 0) )
更笼统的答案。我不知道你想用几周、几个月等做什么
select *
from (SELECT TR.TourID, TR.TourRunTimeStamp, TC.tourName, TC.tourFrequency, TC.Unit, TC.Division
,count(*) OVER (PARTITION BY TR.TourID) AS cnt
FROM dbo.tblTourRun AS TR INNER JOIN
dbo.TSO_PIML_Tour_Config AS TC ON TC.tourID = TR.TourID
WHERE TR.TourRunTimeStamp BETWEEN DATEADD(day, DATEDIFF(day, 0, GETDATE()) - 1, 0) AND DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0))
) t
where cnt <> case TC.tourFrequency when '1xDay' then 1 when '2xDay' then 2 when '4xDay' then 4 end
;
select *
from (SELECT TR.TourID, TR.TourRunTimeStamp, TC.tourName, TC.tourFrequency, TC.Unit, TC.Division, count(*) OVER (PARTITION BY TR.TourID) AS cnt
FROM dbo.tblTourRun AS TR INNER JOIN
dbo.TSO_PIML_Tour_Config AS TC ON TC.tourID = TR.TourID
WHERE (TC.tourFrequency = '2xDay') AND (TR.TourRunTimeStamp BETWEEN DATEADD(day, DATEDIFF(day, 0, GETDATE()) - 1, 0) AND DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0))
) t
where cnt = 1
;
下面是一个人为设计的示例,应该能让您朝着正确的方向前进。我使用 table 组成的值来模拟您尝试使用的数据的形状(去除与示例无关的值)。
select a.TourId
, b.TourDate
from (values
(1, Convert(datetime2(0), N'2016-01-01 00:00:00'))
, (1, Convert(datetime2(0), N'2016-01-01 04:00:00'))
, (1, Convert(datetime2(0), N'2016-01-03 00:00:00'))
, (1, Convert(datetime2(0), N'2016-01-04 00:00:00'))
, (1, Convert(datetime2(0), N'2016-01-04 04:00:00'))
, (1, Convert(datetime2(0), N'2016-01-05 00:00:00'))
, (2, Convert(datetime2(0), N'2016-02-11 00:00:00'))
, (2, Convert(datetime2(0), N'2016-02-11 18:00:00'))
, (2, Convert(datetime2(0), N'2016-02-13 00:00:00'))
, (2, Convert(datetime2(0), N'2016-02-14 00:00:00'))
, (2, Convert(datetime2(0), N'2016-02-14 18:00:00'))
, (2, Convert(datetime2(0), N'2016-02-15 00:00:00'))
) as a (TourId, TourRunTimeStamp)
cross apply (values(Convert(date, a.TourRunTimeStamp))) as b (TourDate)
group by a.TourId
, b.TourDate
having Count(1) != 2; -- find ids with exactly two entries
-- having Count(1) in (2, 4); -- find ids with exactly two or four entries
-- having Count(1) % 2 = 0; -- find ids with an even number of entries
这里的逻辑很简单:将日期时间转换为日期(这是在 APPLY 子句中完成的,以便我们可以重用计算),在 TourId
+ TourDate
,统计记录数,过滤掉所有不等于2的结果。
Final SQL Results:
With the Help of some CTE's or Views I was able to get it working.
- 查询 1- 游览 运行 日期 运行ge(昨天)
- 查询 2 - 摘要在日期戳列上显示没有日期戳的游览为空
- 查询 3 - 错过旅行时的条件计数,所以我为错过的路线显示 0
`--Get All ToursRanYesterday
WITH toursranyesterday
AS (SELECT TR.tourid,
TR.tourruntimestamp,
TC.tourname,
TC.division,
TC.unit,
TC.tourfrequency
FROM dbo.tbltourrun AS TR
INNER JOIN dbo.tso_piml_tour_config AS TC
ON TC.tourid = TR.tourid
WHERE ( TC.tourfrequency LIKE '%xDay%' )
AND ( TR.tourruntimestamp
BETWEEN Dateadd(day, Datediff(day,
0,Getdate()) - 1, 0)
AND
Dateadd(day, Datediff(day,
0, Getdate()), 0) )),
--Get Summary of xDay Tours Ran with Missing Tours
toursummary
AS (SELECT TC.tourid,
TC.division,
TC.unit,
TC.tourname,
TC.tourfrequency,
( CASE
WHEN EXISTS (SELECT *
FROM toursranyesterday AS TY
WHERE TC.tourid = TY.tourid) THEN 'NO'
WHEN NOT EXISTS (SELECT *
FROM toursranyesterday AS TY
WHERE TC.tourid = TY.tourid) THEN 'YES'
END ) AS Missed,
TY.tourruntimestamp
FROM dbo.tso_piml_tour_config AS TC
FULL OUTER JOIN toursranyesterday AS TY
ON TY.tourid = TC.tourid
WHERE ( TC.tourfrequency LIKE '%xDay%' ))
--Add Daily Tour Count when Missed = NO
SELECT TS.tourid,
TS.division,
TS.unit,
TS.tourname,
TS.tourfrequency,
TS.missed,
TS.tourruntimestamp,
Count(CASE
WHEN missed = 'NO' THEN 1
ELSE NULL
END)
OVER (
partition BY TS.tourid) AS [DailyTourCount]
FROM toursummary AS TS
ORDER BY TS.tourname `
问题:我想确定哪些记录每天没有两条记录。 Rank 告诉我每天是否有第二条记录....
SELECT TR.tourid,
TR.tourruntimestamp,
TC.tourname,
TC.tourfrequency,
TC.unit,
TC.division,
RANK()
OVER (
PARTITION BY TR.tourid
ORDER BY TR.tourruntimestamp) AS [Rank]
FROM DBO.tbltourrun AS TR
INNER JOIN DBO.tso_piml_tour_config AS TC
ON TC.tourid = TR.tourid
WHERE ( TC.tourfrequency = '2xDay' )
AND ( TR.tourruntimestamp BETWEEN Dateadd(DAY, Datediff(DAY, 0, Getdate()) - 1, 0) AND Dateadd(DAY, Datediff(DAY, 0, Getdate()), 0) )
更笼统的答案。我不知道你想用几周、几个月等做什么
select *
from (SELECT TR.TourID, TR.TourRunTimeStamp, TC.tourName, TC.tourFrequency, TC.Unit, TC.Division
,count(*) OVER (PARTITION BY TR.TourID) AS cnt
FROM dbo.tblTourRun AS TR INNER JOIN
dbo.TSO_PIML_Tour_Config AS TC ON TC.tourID = TR.TourID
WHERE TR.TourRunTimeStamp BETWEEN DATEADD(day, DATEDIFF(day, 0, GETDATE()) - 1, 0) AND DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0))
) t
where cnt <> case TC.tourFrequency when '1xDay' then 1 when '2xDay' then 2 when '4xDay' then 4 end
;
select *
from (SELECT TR.TourID, TR.TourRunTimeStamp, TC.tourName, TC.tourFrequency, TC.Unit, TC.Division, count(*) OVER (PARTITION BY TR.TourID) AS cnt
FROM dbo.tblTourRun AS TR INNER JOIN
dbo.TSO_PIML_Tour_Config AS TC ON TC.tourID = TR.TourID
WHERE (TC.tourFrequency = '2xDay') AND (TR.TourRunTimeStamp BETWEEN DATEADD(day, DATEDIFF(day, 0, GETDATE()) - 1, 0) AND DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0))
) t
where cnt = 1
;
下面是一个人为设计的示例,应该能让您朝着正确的方向前进。我使用 table 组成的值来模拟您尝试使用的数据的形状(去除与示例无关的值)。
select a.TourId
, b.TourDate
from (values
(1, Convert(datetime2(0), N'2016-01-01 00:00:00'))
, (1, Convert(datetime2(0), N'2016-01-01 04:00:00'))
, (1, Convert(datetime2(0), N'2016-01-03 00:00:00'))
, (1, Convert(datetime2(0), N'2016-01-04 00:00:00'))
, (1, Convert(datetime2(0), N'2016-01-04 04:00:00'))
, (1, Convert(datetime2(0), N'2016-01-05 00:00:00'))
, (2, Convert(datetime2(0), N'2016-02-11 00:00:00'))
, (2, Convert(datetime2(0), N'2016-02-11 18:00:00'))
, (2, Convert(datetime2(0), N'2016-02-13 00:00:00'))
, (2, Convert(datetime2(0), N'2016-02-14 00:00:00'))
, (2, Convert(datetime2(0), N'2016-02-14 18:00:00'))
, (2, Convert(datetime2(0), N'2016-02-15 00:00:00'))
) as a (TourId, TourRunTimeStamp)
cross apply (values(Convert(date, a.TourRunTimeStamp))) as b (TourDate)
group by a.TourId
, b.TourDate
having Count(1) != 2; -- find ids with exactly two entries
-- having Count(1) in (2, 4); -- find ids with exactly two or four entries
-- having Count(1) % 2 = 0; -- find ids with an even number of entries
这里的逻辑很简单:将日期时间转换为日期(这是在 APPLY 子句中完成的,以便我们可以重用计算),在 TourId
+ TourDate
,统计记录数,过滤掉所有不等于2的结果。
Final SQL Results:
With the Help of some CTE's or Views I was able to get it working.
- 查询 1- 游览 运行 日期 运行ge(昨天)
- 查询 2 - 摘要在日期戳列上显示没有日期戳的游览为空
- 查询 3 - 错过旅行时的条件计数,所以我为错过的路线显示 0
`--Get All ToursRanYesterday
WITH toursranyesterday
AS (SELECT TR.tourid,
TR.tourruntimestamp,
TC.tourname,
TC.division,
TC.unit,
TC.tourfrequency
FROM dbo.tbltourrun AS TR
INNER JOIN dbo.tso_piml_tour_config AS TC
ON TC.tourid = TR.tourid
WHERE ( TC.tourfrequency LIKE '%xDay%' )
AND ( TR.tourruntimestamp
BETWEEN Dateadd(day, Datediff(day,
0,Getdate()) - 1, 0)
AND
Dateadd(day, Datediff(day,
0, Getdate()), 0) )),
--Get Summary of xDay Tours Ran with Missing Tours
toursummary
AS (SELECT TC.tourid,
TC.division,
TC.unit,
TC.tourname,
TC.tourfrequency,
( CASE
WHEN EXISTS (SELECT *
FROM toursranyesterday AS TY
WHERE TC.tourid = TY.tourid) THEN 'NO'
WHEN NOT EXISTS (SELECT *
FROM toursranyesterday AS TY
WHERE TC.tourid = TY.tourid) THEN 'YES'
END ) AS Missed,
TY.tourruntimestamp
FROM dbo.tso_piml_tour_config AS TC
FULL OUTER JOIN toursranyesterday AS TY
ON TY.tourid = TC.tourid
WHERE ( TC.tourfrequency LIKE '%xDay%' ))
--Add Daily Tour Count when Missed = NO
SELECT TS.tourid,
TS.division,
TS.unit,
TS.tourname,
TS.tourfrequency,
TS.missed,
TS.tourruntimestamp,
Count(CASE
WHEN missed = 'NO' THEN 1
ELSE NULL
END)
OVER (
partition BY TS.tourid) AS [DailyTourCount]
FROM toursummary AS TS
ORDER BY TS.tourname `