2012-03-17 8 views
2

を解決します。は、私はSQLの私の改善のために、この<a href="http://beyondrelational.com/puzzles/challenges/106/calculate-the-payroll-hours-of-employees.aspx" rel="nofollow">case</a>を解決するために問題を抱えている。このSQLパズル

SELECT 
    a.EmpID, 
    a.EarningCode, 
    c.WeekStart, 
    c.WeekEnd, 
    CAST( (substring(a.EndTime, 1, 2) + '.' + substring(a.EndTime, 4, 2)) AS decimal(4,2) ), 
    CAST( (substring(a.StartTime, 1, 2) + '.' + substring(a.StartTime, 4, 2)) AS decimal(4,2) ), 
    a.EndTime, 
    a.StartTime 
FROM TC72_EmployeeVisits a, TC72_Employees b, TC72_PayrollWeek c 
WHERE a.EmpID = b.EmpID and c.EmpID = a.EmpID and c.EmpID = b.EmpID 
+2

私たちに教えてください。あなたは何をしようとしているのですか?2)これは公開チャレンジコンテストのためのものです。 – RBarryYoung

+0

1. empIDと時間を区別する 2.この場合は、いくつかのキーワードだけです。 –

+0

@FullmetalBoy - 私の解決策に関する意見やコメントはありますか?あなたのコンテストには効果がありますか? –

答えて

0

ここに移動します。楽しかった。挑戦してくれてありがとう。

;WITH cte0 AS 
    (SELECT 'H' AS RecType, 
      e.EmpID, 
      e.EmpName, 
      w.WeekStart, 
      w.WeekEnd, 
      NULL AS EarningCode, 
      NULL AS Hours 
    FROM dbo.TC72_EmployeeVisits v 
    JOIN dbo.TC72_PayrollWeek w ON v.VisitDate BETWEEN w.WeekStart AND w.WeekEnd 
    JOIN dbo.TC72_Employees e ON v.EmpID = e.EmpID 
    GROUP BY e.EmpID, 
      e.EmpName, 
      w.WeekStart, 
      w.WeekEnd 

    UNION 

    SELECT 'D' AS RecType, 
      e.EmpID, 
      e.EmpName, 
      w.WeekStart, 
      w.WeekEnd, 
      v.EarningCode, 
      cast(SUM(DATEDIFF(MINUTE, CONVERT(datetime, v.StartTime), CONVERT(datetime, v.EndTime))) AS float)/60 AS Hours 
    FROM dbo.TC72_EmployeeVisits v 
    JOIN dbo.TC72_PayrollWeek w ON v.VisitDate BETWEEN w.WeekStart AND w.WeekEnd 
    JOIN dbo.TC72_Employees e ON v.EmpID = e.EmpID 
    GROUP BY e.EmpID, 
      e.EmpName, 
      w.WeekStart, 
      w.WeekEnd, 
      v.EarningCode), 
cte1 AS 
    (SELECT ROW_NUMBER() over (ORDER BY EmpId ASC, RecType DESC) AS seq, * 
    FROM cte0), 

cte2 AS 
    (SELECT c1.seq, 
      c1.EmpId, 
      c1.EmpName, 
      c1.WeekStart, 
      c1.WeekEnd, 
      c1.EarningCode, 
      c1.Hours 
    FROM cte1 c1 
    WHERE seq = 1 

    UNION 

    SELECT c2.seq, 
      EmpId = CASE WHEN c1.EmpId = c2.EmpId THEN NULL ELSE c2.EmpId END, 
      EmpName = CASE WHEN c1.EmpName = c2.EmpName THEN '' ELSE c2.EmpName END, 
      WeekStart = CASE WHEN c1.WeekStart = c2.WeekStart THEN NULL ELSE c2.WeekStart END, 
      WeekEnd = CASE WHEN c1.WeekEnd = c2.WeekEnd THEN NULL ELSE c2.WeekEnd END, 
      c2.EarningCode, 
      c2.Hours 
    FROM cte1 c1 
    JOIN cte1 c2 ON c1.seq = c2.seq - 1 
    WHERE c2.seq > 1) 

SELECT EmpId, 
     EmpName, 
     WeekStart, 
     WeekEnd, 
     EarningCode, 
     Hours 
FROM cte2 
ORDER BY seq