在SQL Server中查找时间范围内某些特殊项的计数
假设某人有一个任务,组织应该在任务期间支付他的餐费,但在任务结束之前不支付,例如,如果他在上午8点之后开始任务,他将不会得到任何报酬。 如果他在晚上9点后完成任务,也会是一样的,而不是晚餐时间,午餐时间在12点结束 这是桌子:在SQL Server中查找时间范围内某些特殊项的计数,sql,sql-server,Sql,Sql Server,假设某人有一个任务,组织应该在任务期间支付他的餐费,但在任务结束之前不支付,例如,如果他在上午8点之后开始任务,他将不会得到任何报酬。 如果他在晚上9点后完成任务,也会是一样的,而不是晚餐时间,午餐时间在12点结束 这是桌子: ID Date DepartureTime breakfast Lunch Dinner 1 2018-03-13 2018-03-13 13:12:32.000 True False True 2
ID Date DepartureTime breakfast Lunch Dinner
1 2018-03-13 2018-03-13 13:12:32.000 True False True
2 2018-03-14 NULL True True False
3 2018-03-15 NULL False True True
4 2018-03-16 NULL True True False
5 2018-03-17 2018-03-17 13:00:00.000 False True True
我需要一个查询,在这个查询中,我可以计算出符合支付条件的膳食数量
我想应该通过创建一个时间范围并在需要时使用CASE来解决这个问题
这里,True表示他吃了那顿饭,false表示他没有吃东西。
答案应该是:
早餐:2份;午餐:4天;晚餐:21将每顿饭与时间间隔或确切时间联系起来。例如: 早餐:上午8点至10点 午餐:从上午12点到下午2点 晚餐时间:晚上7点至10点 示例如下:
IF OBJECT_ID('tempdb..#MealTime') IS NOT NULL
DROP TABLE #MealTime
CREATE TABLE #MealTime (
Meal VARCHAR(100),
StartTime TIME,
EndTime TIME)
INSERT INTO #MealTime (
Meal,
StartTime,
EndTime)
SELECT
Meal = 'Breakfast',
StartTime = '08:00',
EndTime = '10:00'
UNION ALL
SELECT
Meal = 'Lunch',
StartTime = '12:00',
EndTime = '14:00'
UNION ALL
SELECT
Meal = 'Dinner',
StartTime = '19:00',
EndTime = '22:00'
2确定每行的出发时间表示开始还是结束,并创建时间间隔以简化步骤3:
;WITH Limits AS
(
SELECT
MinimumID = MIN(M.ID),
MaximumID = MAX(M.ID)
FROM
OperationDetails AS M
)
SELECT
M.*,
StartTime = CONVERT(TIME,
CASE
WHEN L1.MinimumID IS NOT NULL THEN M.DepartureTime
ELSE '00:00' END),
EndTime = CONVERT(TIME,
CASE
WHEN L2.MaximumID IS NOT NULL THEN M.DepartureTime
ELSE '23:59' END)
FROM
OperationDetails AS M
LEFT JOIN Limits AS L1 ON M.ID = L1.MinimumID
LEFT JOIN Limits AS L2 ON M.ID = L2.MaximumID
3如果每顿饭都吃了,且时间重叠,则计算每顿饭的数量:
;WITH Limits AS
(
SELECT
MinimumID = MIN(M.ID),
MaximumID = MAX(M.ID)
FROM
OperationDetails AS M
),
MissionTimes AS
(
SELECT
M.*,
StartTime = CONVERT(TIME,
CASE
WHEN L1.MinimumID IS NOT NULL THEN M.DepartureTime
ELSE '00:00' END),
EndTime = CONVERT(TIME,
CASE
WHEN L2.MaximumID IS NOT NULL THEN M.DepartureTime
ELSE '23:59' END)
FROM
OperationDetails AS M
LEFT JOIN Limits AS L1 ON M.ID = L1.MinimumID
LEFT JOIN Limits AS L2 ON M.ID = L2.MaximumID
)
SELECT
AmountBreakfastToPay = COUNT(CASE WHEN M.Breakfast = 'true' AND M.StartTime <= BR.EndTime AND M.EndTime >= BR.StartTime THEN 1 END),
AmountLunchToPay = COUNT(CASE WHEN M.Lunch = 'true' AND M.StartTime <= LU.EndTime AND M.EndTime >= LU.StartTime THEN 1 END),
AmountDinnerToPay = COUNT(CASE WHEN M.Dinner = 'true' AND M.StartTime <= DI.EndTime AND M.EndTime >= DI.StartTime THEN 1 END)
FROM
MissionTimes AS M
INNER JOIN #MealTime AS BR ON BR.Meal = 'Breakfast'
INNER JOIN #MealTime AS LU ON LU.Meal = 'Lunch'
INNER JOIN #MealTime AS DI ON DI.Meal = 'Dinner'
有了这些样本数据,预期的结果是什么?你能告诉我们你当前的查询尝试吗?对我来说毫无意义。当你不能解决它的时候,你为什么要投反对票,我已经解释得够多了,当你没有资格解决它的时候,就别管它了!!!出发时间是否意味着任务的开始时间ID=1和结束时间ID=5?为什么出发时间与ID 5上的日期不匹配?不幸的是,是的,任务a的开始时间和结束时间由出发时间规定,是他离开家或完成任务的时间。
SELECT *
,B=CASE WHEN (cast(DepartureTime AS time) between '00:00:00' AND '08:00:00' OR DepartureTime IS NULL) AND [Breakfast]='True' THEN 1 END
,L=CASE WHEN (cast(DepartureTime AS time) between '08:00:01' AND '13:00:00' OR DepartureTime IS NULL) AND [Lunch]='True' THEN 1 END
,D=CASE WHEN (cast(DepartureTime AS time) between '13:00:01' AND '20:00:00' OR DepartureTime IS NULL) AND [Dinner]='True' THEN 1 END
FROM MissionToEat