从复杂的SQL语句中筛选出特定的结果并清理我的SQL

时间:2017-09-05 20:06:41

标签: sql-server-2008-r2

我正在结合以下表格来确定,进出时间,当天的总工作时数,工作中心和相关的工资率。但是,当PunchType ='303'时,有两行,1表示初始工作中心为'10'拳,然后是'303'当'303拳击存在时,我需要将其用作打卡。下面的查询和示例结果显示我缩小了我的查询以显示使用'10'打孔(in) - '12'打孔(输出)和'303'打孔(输入)的结果(如果它存在) '12'拳(出)。在我的最终结果中,我只想要“303” - “12”匹配,如果它存在或我将有重复记录。所有这些都被转储到Report Builder 3.0中,以计算每天工作的总工时数和每天支付的数额(不需要那里的帮助,只是试图给出一些背景信息)

我已将RowNumber包含在最终查询结果中,因为我正在考虑使用它来根据需要过滤结果。我的想法:如果Count(RowNumber)= 2,返回RowNumber ='2',IF Count(RowNumber)= 1,返回RowNumber ='1',IF Count(RowNumber)= 4,返回RowNumber ='3, 4)。知道这里的措辞语法是错误的,但我只是用它来说明我想要做的事情。我确信有一种更简单的方法来编写查询(尽管如果没有,我也可以),只要我能弄清楚如何将结果过滤到我需要的内容。任何帮助表示赞赏。谢谢!

示例数据:

Timecard
| TimeCardID                         |  StoreID  | EmpID | CardDate         
|   PunchType | WorkCenter | BreakIndex |ShadowTimeCardForID
B6B839AD-D8DF-E611-A3E5-0019170149B6 | 32365     | 4171  |2017-01-21 07:54:00.500 
| 303         | 4          |0           | 00000000-0000-0000-0000-000000000000

EmployeeRate
| EmployeeRateID                         | EmployeeID                         
|   RateIndex | WorkCenter | OvertimeRate | RegularRate
| C3325A54-E7A9-E611-A16D-0019178089A7   | 27139B5C-7A74-E611-969E-3417EBD1A8D1
| 4           | 4          | 2250         |1500

查询:

DECLARE @datetime datetime = '2017-01-22 04:00:00.000'
SELECT
z.EmpID,
z.RegularRate,
z.OvertimeRate,
z.WorkCenter,
z.in_punch,
z.out_punch,
z.HoursWorked,
z.RowNumber
FROM  
(SELECT
  y.EmpID,
  y.RegularRate,
  y.OvertimeRate,
  y.WorkCenter,
  y.in_punch,
  y.out_punch,
  y.HoursWorked,
  row_number() OVER(PARTITION BY EmpID ORDER BY EmpiD) AS RowNumber
FROM  
(SELECT 
  f.EmpID,
  f.RegularRate,
  f.OvertimeRate,
  f.WorkCenter,
  f.in_punch,
  f.out_punch,
  f.HoursWorked
FROM
(SELECT
  tc.EmpID,
  er.RegularRate,
  er.OvertimeRate,
  tc.WorkCenter,
  tc.in_punch,
  tc.out_punch,
  CONVERT(varchar(3),DATEDIFF(MINUTE,in_punch,out_punch)/60) + ':' +
  RIGHT('0' + CONVERT(varchar(2),DATEDIFF(MINUTE,in_punch,out_punch)%60),2) 
AS HoursWorked,
  row_number() OVER(PARTITION BY tc.EmpID ORDER BY tc.EmpiD) AS RowNumber
FROM
(SELECT
    e.EmpID,
    e.WorkCenter,
    e.CardDate AS in_punch,
    e2.CardDate AS out_punch
FROM
   (SELECT EmpID, CardDate, WorkCenter FROM TimeCard where PunchType = '10' 
AND CardDate BETWEEN DATEADD(DAY, -1, @datetime) AND @datetime) e
INNER JOIN
(SELECT EmpID, CardDate, WorkCenter
FROM TimeCard where PunchType = '12' AND CardDate BETWEEN DATEADD(DAY, -1, 
@datetime) AND @datetime) e2 
ON
    e.EmpID = e2.EmpID
) tc
INNER JOIN
[dbo].[Employee] em
ON tc.EmpID = em.EmpID
INNER JOIN
  [dbo].[EmployeeRate] er
  ON em.[EmployeeID] = er.[EmployeeID] AND tc.[Workcenter] = er.[WorkCenter]
WHERE tc.in_punch <= tc.out_punch
GROUP BY tc.EmpID,
  er.RegularRate,
  er.OvertimeRate,
  tc.WorkCenter,
  tc.in_punch,
  tc.out_punch
) f
WHERE f.[RowNumber] <> '2'
UNION
SELECT 
  f.EmpID,
  f.RegularRate,
  f.OvertimeRate,
  f.WorkCenter,
  f.in_punch,
  f.out_punch,
  f.HoursWorked
 FROM
  (SELECT
    tc.EmpID,
    er.RegularRate,
    er.OvertimeRate,
    tc.WorkCenter,
    tc.in_punch,
    tc.out_punch,
    CONVERT(varchar(3),DATEDIFF(MINUTE,in_punch,out_punch)/60) + ':' +
    RIGHT('0' + 
    CONVERT(varchar(2),DATEDIFF(MINUTE,in_punch,out_punch)%60),2) AS 
    HoursWorked,
    row_number() OVER(PARTITION BY tc.EmpID ORDER BY tc.EmpiD) AS RowNumber
FROM
(SELECT
    e.EmpID,
    e.WorkCenter,
    e.CardDate AS in_punch,
    e2.CardDate AS out_punch
FROM
    (SELECT EmpID, CardDate, WorkCenter
FROM TimeCard where PunchType = '303' AND CardDate BETWEEN DATEADD(DAY, -1, 
@datetime) AND @datetime) e
INNER JOIN
  (SELECT EmpID, CardDate, WorkCenter
  FROM TimeCard where PunchType = '12' AND CardDate BETWEEN DATEADD(DAY, -1, 
  @datetime) AND @datetime) e2 
  ON
    e.EmpID = e2.EmpID
) tc
INNER JOIN
  [dbo].[Employee] em
  ON tc.EmpID = em.EmpID
INNER JOIN
  [dbo].[EmployeeRate] er
  ON em.[EmployeeID] = er.[EmployeeID] AND tc.[Workcenter] = er.[WorkCenter]
WHERE tc.in_punch <= tc.out_punch 
GROUP BY tc.EmpID,
  er.RegularRate,
  er.OvertimeRate,
  tc.WorkCenter,
  tc.in_punch,
  tc.out_punch
) f
WHERE f.[RowNumber] <> '2'
) y
) z
GROUP BY
  z.EmpID,
  z.RegularRate,
  z.OvertimeRate,
  z.WorkCenter,
  z.in_punch,
  z.out_punch,
  z.HoursWorked,
  z.RowNumber   
ORDER BY COUNT(RowNumber)OVER(PARTITION BY EmpID)

结果:

EmpID,RegularRate,OvertimeRate,WorkCenter,in_punch,out_punch,HoursWorked,RowNumber
9267,1150,1725,9,2017-01-21 16:59:27.940,2017-01-22 01:16:16.200,8:17, 1
9438,550,825,3,2017-01-21 09:55:34.500,2017-01-21 15:37:51.770,5:42,1
9471,223,335,1,2017-01-21 10:32:08.060,2017-01-21 14:18:23.430,3:46,1
9471,223,335,1,2017-01-21 15:54:29.570,2017-01-21 23:00:00.000,7:06,2
4171,223,335,1,2017-01-21 07:54:00.490,2017-01-21 15:17:31.740,7:23,1
4171,1500,2250,4,2017-01-21 07:54:00.500,2017-01-21 15:17:31.740,7:23,2

0 个答案:

没有答案