想象一下,有人执行任务,组织应该在执行任务期间支付他的膳食费用,但不能在此之后支付费用,例如,如果他在早上8点之后开始执行任务,他将无法获得任何支付。 如果他在晚上9点之后完成任务,这将是相同的,这不是晚餐时间,午餐时间结束于12:00
这里有桌子:
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 WHEN
这里真实意味着他吃了那顿饭,虚假意味着他没有吃饭。 答案应该是:
早餐:2
;午餐:4
;晚餐:2
答案 0 :(得分:1)
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
答案 1 :(得分:0)
1)将每餐与时间间隔(或只是确切的时间)联系起来。例如:
此处示例:
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)确定DepartureTime
是否代表每一行的开头或结尾,并创建时间间隔以使步骤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'