SQL Query生成报告

问题描述 投票:0回答:2

我有三张桌子:

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,所以寻求帮助。

请指导。

sql sql-server sql-server-2008 sql-server-2012
2个回答
0
投票

这是一种使用临时表的方法。

-- 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;

0
投票

下面是我为该问题编写的代码:

    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
© www.soinside.com 2019 - 2024. All rights reserved.