我有三张桌子:
EMP
EmpId EmpName
51894 Alex
51899 Peter
51901 Sam
EmpPunch
PunchId EmpId BusinessDate PunchIn PunchOut
15896 51894 12/18/2017 7:30:00 AM 5:30:00 PM
15897 51894 12/19/2017 7:30:00 AM 5:30:00 PM
15898 51899 12/18/2017 7:30:00 AM 5:30:00 PM
15899 51901 12/18/2017 7:30:00 AM 5:30:00 PM
EmpMeals
MealID PunchID MealStart MealEnd
40725 15896 12/18/2017 9:00 12/18/2017 10:00
40726 15896 12/18/2017 11:30 12/18/2017 12:30
40727 15897 12/19/2017 9:00 12/19/2017 10:00
40728 15897 12/19/2017 11:30 12/19/2017 12:30
40729 15898 12/18/2017 9:00 12/18/2017 10:00
我需要编写一个查询来生成以下格式的报告:
EmpId EmpName BusinessDate PunchIn Meal 1 Start Meal 1 End Meal 1 Duration Meal 2 Start Meal 2 End Meal 2 Duration PunchOut
51894 Alex 12/18/2017 7:30:00 AM 9:00:00 AM 10:00:00 AM 1.00 11:30:00 AM 12:30:00 PM 1.00 5:30:00 PM
51894 Alex 12/19/2017 7:30:00 AM 9:00:00 AM 10:00:00 AM 1.00 11:30:00 AM 12:30:00 PM 1.00 5:30:00 PM
51899 Peter 12/18/2017 7:30:00 AM 9:00:00 AM 10:00:00 AM 1.00 5:30:00 PM
51901 Sam 12/18/2017 7:30:00 AM 5:30:00 PM
注意事项:
a. Employee can have any number of meals. But we are considering first two.
b. If employee has availed only one meal, then for 2nd meal start and end time, NULL will be displayed.
c. If employee has not availed any meals then his record will not appear in EmpMeals table.
现在,我写的查询是在多行中获取记录。我不是很精通SQL,所以寻求帮助。
请指导。
这是一种使用临时表的方法。
-- First assign meal numbers per PunchID in order of MealStart time
SELECT ROW_NUMBER() OVER ( PARTITION BY EM.PunchID ORDER BY EM.MealStart ) AS MEALNUMBER
, EM.*
INTO #MEALS
FROM EmployeeMeal EM;
-- Then join the first two meals of each PunchID into a single row
SELECT
EM1.PunchID
, EM1.MealStart MealStart1
, EM1.MealEnd MealEnd1
, DateDiff(MINUTE, EM1.MealStart, EM1.MealEnd)/60.0 MealDuration1
, EM2.MealStart MealStart2
, EM2.MealEnd MealEnd2
, DateDiff(MINUTE, EM2.MealStart, EM2.MealEnd)/60.0 MealDuration2
INTO #PUNCHES
FROM #MEALS EM1
LEFT JOIN #MEALS EM2
ON EM1.PunchID = EM2.PunchID
AND EM2.MEALNUMBER = 2
WHERE EM1.MEALNUMBER = 1;
-- Finally join the employee and punch details with the meal details
SELECT E.EmpID
, E.EmpName
, EP.BusinessDate
, CAST(ISNULL( FORMAT(PP.MealStart1, 'h:mm tt'), '') as varchar(10)) [Meal 1 Start]
, CAST(ISNULL( FORMAT(PP.MealEnd1, 'h:mm tt'), '') as varchar(10)) [Meal 1 End]
, ISNULL(PP.MealDuration1, 0) [Meal 1 Duration]
, CAST(ISNULL( FORMAT(PP.MealStart2, 'h:mm tt'), '') as varchar(10)) [Meal 2 Start]
, CAST(ISNULL( FORMAT(PP.MealEnd2, 'h:mm tt'), '') as varchar(10)) [Meal 2 End]
, ISNULL(PP.MealDuration2, 0) [Meal 2 Duration]
FROM Employee E
JOIN EmployeePunch EP
ON E.EmpID = EP.EmpID
LEFT JOIN #PUNCHES PP
ON PP.PunchID = EP.Punchid
;
DROP TABLE #PUNCHES;
DROP TABLE #MEALS;
下面是我为该问题编写的代码:
SELECT
E.EmpId EmpId,
E.EmpName,
EP.PunchId PunchId,
EP.BusinessDate BusinessDate,
FORMAT(EP.StartTime, 'hh:mm tt') InTime,
FORMAT(EP.EndTime, 'hh:mm tt') OutTime,
MAX(CASE WHEN EPMBTemp.DefNum = 1 THEN FORMAT(EPMB.StartTime, 'hh:mm tt') END) MealOut1,
MAX(CASE WHEN EPMBTemp.DefNum = 1 THEN FORMAT(EPMB.EndTime, 'hh:mm tt') END) MealIn1,
MAX(CASE WHEN EPMBTemp.DefNum = 1 THEN DATEDIFF(MINUTE,EPMB.StartTime,EPMB.EndTime)/60.0 END) Meal1Length,
MAX(CASE WHEN EPMBTemp.DefNum = 2 THEN FORMAT(EPMB.StartTime,'hh:mm tt') END) MealOut2,
MAX(CASE WHEN EPMBTemp.DefNum = 2 THEN FORMAT(EPMB.EndTime,'hh:mm tt') END) MealIn2,
MAX(CASE WHEN EPMBTemp.DefNum = 2 THEN DATEDIFF(MINUTE,EPMB.StartTime,EPMB.EndTime)/60.0 END) Meal2Length
FROM EmpPunch EP
LEFT JOIN
(
SELECT ROW_NUMBER () OVER (PARTITION BY PunchId ORDER BY PunchId ) AS DefNum, PunchId, MealPunchId
FROM
(
SELECT DISTINCT EPMB.PunchId, EPMB.MealPunchId
FROM EmpMealPunch EPMB
)Temp
)EPMBTemp ON EPMBTemp.PunchId = EP.PunchId
LEFT JOIN EmpMealPunch EPMB ON EPMB.MealPunchId = EPMBTemp.MealPunchId
JOIN Emp E ON EP.EmpId = E.EmpId
group by E.EmpId, E.EmpName, EP.BusinessDate, EP.PunchId, EP.StartTime, EP.EndTime