问题:我想确定哪些记录每天没有两条记录。排名告诉我每天是否有第二条记录......
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) )
答案 0 :(得分:1)
更一般的答案。我不知道你想用几周,几个月等做什么。
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
;
答案 1 :(得分:1)
下面是一个人为的例子,它可以让你朝着正确的方向前进。我使用一个由值组成的表来模拟您尝试使用的数据的形状(剥离与该示例无关的值)。
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
+ {{ 1}},计算记录数,并过滤掉所有没有等于2的计数的结果。
答案 2 :(得分:0)
最终SQL结果:
在一些CTE或视图的帮助下,我能够使其正常工作。
`--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 `