如何避免在Select语句中包括哪些聚集功能的分组依据

时间:2019-01-08 08:01:22

标签: sql-server

大家早上好。

我正在尝试开发一个出勤报告,该报告根据我不想按设备分组的日志详细信息显示In&OUT时间,否,这使我为每个条目重复了值。是他们避免按设备名称分组的任何方法。查询如下。查询的第二部分与T2.alias相同

SELECT 
T1.[PUNCH DATE], 
T1.[TOKEN NO], 
T1.[NAME],
T1.[DESIGNATION], 
T1.[DEPT.], 
T1.[PROJECT NO.],
T1.[F.CODE.],  
T1.[W.DAYS], 
T1.[SHIFT STARTS], 
T1.[SHIFT ENDS], 
T1.[BREAK MIN.] ,  
MIN(T1.[TIME IN])'TIME IN',
T1.[DEVICE IN]'DEVICE IN',
MAX(T2.[TIME OUT])'TIME OUT',
T2.[DEVICE OUT]'DEVICE OUT',
CONVERT(VARCHAR(5), DATEADD(MINUTE, (DATEDIFF(MI, T1.[TIME IN], T2.[TIME OUT]))-DATEDIFF(MI,(0),T1.[BREAK MIN.]),0),108) 'TOT.HRS.',

T1.[DAY/NIGHT]

FROM(SELECT

EMP_Event_Log.EMP_Punch_Date 'PUNCH DATE',  
EMP_Event_Log.EMP_Token_No 'TOKEN NO', 
QTB_EMP_Project_Allocation.EMP_Name 'NAME',
QTB_EMP_Project_Allocation.EMP_Designation 'DESIGNATION', 
QTB_EMP_Project_Allocation.EMP_Dept_No 'DEPT.', 
QTB_EMP_Project_Allocation.EMP_Project_No 'PROJECT NO.', 
QTB_EMP_Project_Allocation.EMP_FCode 'F.CODE.', 
QTB_EMP_Project_Allocation.EMP_W_Days 'W.DAYS', 
QTB_EMP_Project_Allocation.EMP_Shift_Starts 'SHIFT STARTS', 
QTB_EMP_Project_Allocation.EMP_Shift_End 'SHIFT ENDS', 
QTB_EMP_Project_Allocation.EMP_Break_Mins 'BREAK MIN.' ,  
MIN(EMP_Event_Log.EMP_Punch_Time) 'TIME IN',
EMP_Event_Log.EMP_Device_No 'DEVICE IN',
QTB_EMP_Project_Allocation.EMP_Shift_Type 'DAY/NIGHT' 
FROM
EMP_Event_Log JOIN
QTB_EMP_Project_Allocation ON EMP_Event_Log.EMP_Token_No = QTB_EMP_Project_Allocation.EMP_Token_No AND QTB_EMP_Project_Allocation.EMP_Project_To IS NULL OR
EMP_Event_Log.EMP_Punch_Date<=QTB_EMP_Project_Allocation.EMP_Project_To
WHERE 
EMP_Event_Log.EMP_Punch_Date =@Local_@SDate AND 
QTB_EMP_Project_Allocation.EMP_Shift_Type='DAY' AND
EMP_Event_Log.EMP_Token_No = QTB_EMP_Project_Allocation.EMP_Token_No AND QTB_EMP_Project_Allocation.EMP_Project_No=@Local_@FCode

GROUP BY
EMP_Event_Log.EMP_Token_No, 
QTB_EMP_Project_Allocation.EMP_Name,
EMP_Event_Log.EMP_Punch_Date, 
QTB_EMP_Project_Allocation.EMP_Designation, 
QTB_EMP_Project_Allocation.EMP_Dept_No, 
QTB_EMP_Project_Allocation.EMP_Project_No, 
QTB_EMP_Project_Allocation.EMP_FCode, 
QTB_EMP_Project_Allocation.EMP_W_Days, 
QTB_EMP_Project_Allocation.EMP_Shift_Starts, 
QTB_EMP_Project_Allocation.EMP_Shift_End, 
QTB_EMP_Project_Allocation.EMP_Break_Mins,
EMP_Event_Log.EMP_Device_No,
QTB_EMP_Project_Allocation.EMP_Shift_Type

HAVING
(MIN(EMP_Event_Log.EMP_Punch_Time)<>'00:00:00.0000000' OR MAX(EMP_Event_Log.EMP_Punch_Time)<>'00:00:00.0000000') AND
CAST(CONVERT(VARCHAR(5), MIN(EMP_Event_Log.EMP_Punch_Time),113)AS TIME)<>CAST(CONVERT(VARCHAR(5),MAX(EMP_Event_Log.EMP_Punch_Time),113)AS TIME))AS T1 

JOIN(

SELECT
EMP_Event_Log.EMP_Punch_Date 'PUNCH DATE', 
EMP_Event_Log.EMP_Token_No 'TOKEN NO', 
QTB_EMP_Project_Allocation.EMP_Name 'NAME',
QTB_EMP_Project_Allocation.EMP_Designation 'DESIGNATION', 
QTB_EMP_Project_Allocation.EMP_Dept_No 'DEPT.', 
QTB_EMP_Project_Allocation.EMP_Project_No 'PROJECT NO.',
QTB_EMP_Project_Allocation.EMP_FCode 'F.CODE.',  
QTB_EMP_Project_Allocation.EMP_W_Days 'W.DAYS', 
QTB_EMP_Project_Allocation.EMP_Shift_Starts 'SHIFT STARTS', 
QTB_EMP_Project_Allocation.EMP_Shift_End 'SHIFT ENDS', 
QTB_EMP_Project_Allocation.EMP_Break_Mins 'BREAK MIN.' ,  
MAX(EMP_Event_Log.EMP_Punch_Time) 'TIME OUT',
EMP_Event_Log.EMP_Device_No 'DEVICE OUT',
QTB_EMP_Project_Allocation.EMP_Shift_Type 'DAY/NIGHT'
FROM
EMP_Event_Log JOIN
QTB_EMP_Project_Allocation ON EMP_Event_Log.EMP_Token_No = QTB_EMP_Project_Allocation.EMP_Token_No AND QTB_EMP_Project_Allocation.EMP_Project_To IS NULL OR
EMP_Event_Log.EMP_Punch_Date<=QTB_EMP_Project_Allocation.EMP_Project_To
WHERE 
EMP_Event_Log.EMP_Punch_Date=@Local_@SDate AND 
QTB_EMP_Project_Allocation.EMP_Shift_Type='DAY' AND
EMP_Event_Log.EMP_Token_No = QTB_EMP_Project_Allocation.EMP_Token_No AND QTB_EMP_Project_Allocation.EMP_Project_No=@Local_@FCode

GROUP BY
EMP_Event_Log.EMP_Token_No, 
QTB_EMP_Project_Allocation.EMP_Name,
EMP_Event_Log.EMP_Punch_Date, 
QTB_EMP_Project_Allocation.EMP_Designation, 
QTB_EMP_Project_Allocation.EMP_Dept_No, 
QTB_EMP_Project_Allocation.EMP_Project_No,
QTB_EMP_Project_Allocation.EMP_FCode,  
QTB_EMP_Project_Allocation.EMP_W_Days, 
QTB_EMP_Project_Allocation.EMP_Shift_Starts, 
QTB_EMP_Project_Allocation.EMP_Shift_End, 
QTB_EMP_Project_Allocation.EMP_Break_Mins,
EMP_Event_Log.EMP_Device_No,
QTB_EMP_Project_Allocation.EMP_Shift_Type

HAVING 
(MIN(EMP_Event_Log.EMP_Punch_Time)<>'00:00:00.0000000' OR MAX(EMP_Event_Log.EMP_Punch_Time)<>'00:00:00.0000000')AND
CAST(CONVERT(VARCHAR(5), MIN(EMP_Event_Log.EMP_Punch_Time),113) AS TIME)<>CAST(CONVERT(VARCHAR(5),MAX(EMP_Event_Log.EMP_Punch_Time),113) AS TIME))T2 on T1.[TOKEN NO]=T2.[TOKEN NO]
GROUP BY 
T1.[PUNCH DATE],
T1.[TOKEN NO],
T1.[NAME],
T1.[DESIGNATION], 
T1.[DEPT.], 
T1.[PROJECT NO.], 
T1.[F.CODE.], 
T1.[W.DAYS], 
T1.[SHIFT STARTS], 
T1.[SHIFT ENDS], 
T1.[BREAK MIN.] ,  
T1.[TIME IN],
T1.[DAY/NIGHT],
T2.[TIME OUT],
T1.[DEVICE IN],
t2.[DEVICE OUT]
ORDER BY T1.[TIME IN]

1 个答案:

答案 0 :(得分:2)

我的理解:

  • Device NoEMP_Event_Log记录的非关键属性。
  • 您想与特定的“打卡时间”关联Device No

解决方案:

最简单的方法是通过Window Functions。 类似于:

SELECT *
FROM(SELECT *,
    ROW_NUMBER() OVER( PARTITION BY 
    -- This is where your current Group By columns go
    EMP_Event_Log.EMP_Token_No, 
    QTB_EMP_Project_Allocation.EMP_Name,
    EMP_Event_Log.EMP_Punch_Date, 
    QTB_EMP_Project_Allocation.EMP_Designation, 
    QTB_EMP_Project_Allocation.EMP_Dept_No, 
    QTB_EMP_Project_Allocation.EMP_Project_No, 
    QTB_EMP_Project_Allocation.EMP_FCode, 
    QTB_EMP_Project_Allocation.EMP_W_Days, 
    QTB_EMP_Project_Allocation.EMP_Shift_Starts, 
    QTB_EMP_Project_Allocation.EMP_Shift_End, 
    QTB_EMP_Project_Allocation.EMP_Break_Mins,
    -- You can now exclude EMP_Event_Log.EMP_Device,
    QTB_EMP_Project_Allocation.EMP_Shift_Type
    ORDER BY 
    EMP_Event_Log.EMP_Punch_Time ASC ) AS FirstIn,
    -- Same as above except ASC becomes DESC
    ROW_NUMBER() OVER( PARTITION BY ..... ORDER BY EMP_Event_Log.EMP_Punch_Time DESC ) AS LastOut
FROM
    EMP_Event_Log JOIN
    QTB_EMP_Project_Allocation ON EMP_Event_Log.EMP_Token_No = QTB_EMP_Project_Allocation.EMP_Token_No AND QTB_EMP_Project_Allocation.EMP_Project_To IS NULL OR
    EMP_Event_Log.EMP_Punch_Date<=QTB_EMP_Project_Allocation.EMP_Project_To
    WHERE 
    EMP_Event_Log.EMP_Punch_Date =@Local_@SDate AND 
    QTB_EMP_Project_Allocation.EMP_Shift_Type='DAY' AND
    EMP_Event_Log.EMP_Token_No = QTB_EMP_Project_Allocation.EMP_Token_No AND QTB_EMP_Project_Allocation.EMP_Project_No=@Local_@FCode
) AS Processed
WHERE ( FirstIn = 1 OR LastOut = 1 ) AND EMP_Event_Log.EMP_Punch_Time <> '00:00:00.0000000' AND NOT( FirstIn = 1 AND LastOut = 1 )
ORDER BY ...