2015-02-23 20 views
1

我面臨一個問題,試圖爲工資報告提供一個MySQL存儲過程。以前的員工工資率只允許在薪酬期間開始時更改。但是,現在他們可以在支付期間進行更改,並且報告需要在支付期間考慮不同的工資率。支付期限爲兩週。MySQL存儲過程 - 計算付費差異

我有以下查詢,這是非常混亂,它的工作原理,但沒有考慮到薪酬階段中的薪酬變化。

注:日期是硬編碼作爲一個例子

SELECT 
    e.EmployeeID AS EmployeeID, 
    CONCAT(e.LastName, ', ', e.FirstName) AS Resource, 
    (SELECT rt.Description FROM Roles rt WHERE rt.RoleId = e.RoleId) as Role, 
    (
     SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td, 
      Projects p 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND p.ProjectID = td.ProjectID 
     AND p.ProjectID NOT IN (24,29,606,614,746) 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS RegularHours, 
    (
     SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td, 
      Projects p 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND p.ProjectID = td.ProjectID 
     AND (p.ProjectID = 29 OR p.ProjectID = 614) 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS PTO, 
    (
     SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td, 
      Projects p 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND p.ProjectID = td.ProjectID 
     AND p.ProjectID = 24 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS Holiday, 
    (
     SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td, 
      Projects p 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND p.ProjectID = td.ProjectID 
     AND p.ProjectID = 746 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS FloatingHoliday, 
    (
     SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND td.ProjectID NOT IN (606) 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS Total, 
    (
     SELECT 
      epr.Rate 

     FROM 
      EmployeePayRate epr , 
      Timesheets t, 
      TimesheetDetails td 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND epr.EmployeeID = t.EmployeeID 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
     AND epr.StartDate <= td.WorkDate 
     ORDER BY epr.StartDate DESC 
     LIMIT 1 
    ) AS PayRate, 
    (
     (SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND td.ProjectID NOT IN (606) 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
     ) 

     * 

     (SELECT 
      epr.Rate 
     FROM 
      EmployeePayRate epr , 
      Timesheets t, 
      TimesheetDetails td 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND epr.EmployeeID = t.EmployeeID 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
     AND epr.StartDate <= td.WorkDate 
     ORDER BY epr.StartDate DESC 
     LIMIT 1) 
    ) AS GrossEarnings 

FROM 
    Employee e 
WHERE (e.EmployeeID IN (SELECT t.EmployeeID 
    FROM TimesheetDetails tsd, Timesheets t 
    WHERE tsd.BillableHours > 0 
    AND tsd.WorkDate BETWEEN '2015-01-17' AND '2015-01-30' 
    AND tsd.TimeCardID = t.TimeCardID 
    ) OR e.Status = 'Active') 
AND (e.ResourceTypeID = 2 OR e.ResourceTypeID = 4) 
GROUP BY Resource 
ORDER BY Role, Resource ASC 

最終報告的列應。

EmployeeID,LastName,FirstName,RegularHours,PTO,Holiday,FloatingHoliday,Total和GrossEarnings。

我對存儲過程並不是很有經驗,但我想我需要使用遊標來遍歷每個日期並計算出應用於此的付費率。

無論如何,這個SQL將創建數據結構。

-- MySQL dump 10.13 Distrib 5.6.17, for Win64 (x86_64) 
-- 
-- Host: localhost Database: timesheet_test 
-- ------------------------------------------------------ 
-- Server version 5.6.22-log 

/*!40101 SET @[email protected]@CHARACTER_SET_CLIENT */; 
/*!40101 SET @[email protected]@CHARACTER_SET_RESULTS */; 
/*!40101 SET @[email protected]@COLLATION_CONNECTION */; 
/*!40101 SET NAMES utf8 */; 
/*!40103 SET @[email protected]@TIME_ZONE */; 
/*!40103 SET TIME_ZONE='+00:00' */; 
/*!40014 SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 
/*!40014 SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 
/*!40101 SET @[email protected]@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 
/*!40111 SET @[email protected]@SQL_NOTES, SQL_NOTES=0 */; 

-- 
-- Table structure for table `employee` 
-- 

DROP TABLE IF EXISTS `employee`; 
/*!40101 SET @saved_cs_client  = @@character_set_client */; 
/*!40101 SET character_set_client = utf8 */; 
CREATE TABLE `employee` (
    `EmployeeID` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `FirstName` varchar(25) NOT NULL, 
    `LastName` varchar(30) NOT NULL, 
    `Address` varchar(255) DEFAULT NULL, 
    `CountryID` int(10) unsigned DEFAULT NULL, 
    `Phone1` varchar(50) DEFAULT NULL, 
    `Phone2` varchar(50) DEFAULT NULL, 
    `ClientSitePhone` varchar(50) DEFAULT NULL, 
    `Email` varchar(150) DEFAULT NULL, 
    `PersonalEmail` varchar(150) DEFAULT NULL, 
    `ClientEmail` varchar(150) DEFAULT NULL, 
    `Comments` longtext, 
    `HRComments` longtext, 
    `Status` varchar(10) DEFAULT NULL, 
    `Expertise` varchar(100) DEFAULT NULL, 
    `Years` varchar(10) DEFAULT NULL, 
    `Payroll` tinyint(1) NOT NULL DEFAULT '1', 
    `PartTime` tinyint(1) NOT NULL DEFAULT '0', 
    `City` varchar(100) DEFAULT '', 
    `State` varchar(2) DEFAULT NULL, 
    `Zip` varchar(20) DEFAULT NULL, 
    `DateOfBirth` date DEFAULT NULL, 
    `RoleId` int(10) unsigned DEFAULT NULL, 
    `ImmiId` int(10) unsigned DEFAULT NULL, 
    `ResourceTypeId` int(10) unsigned DEFAULT NULL, 
    `UnderHoursAlerts` tinyint(1) NOT NULL DEFAULT '1', 
    `DateHired` date DEFAULT NULL, 
    `DateLastWorked` date DEFAULT NULL, 
    `RecruiterEmployeeID` int(10) unsigned DEFAULT NULL, 
    `PrimaryPhone` varchar(1) DEFAULT 'H', 
    `PreHire` tinyint(1) NOT NULL DEFAULT '0', 
    `SSN` varchar(132) DEFAULT NULL, 
    `Benefits` varchar(100) NOT NULL DEFAULT 'None', 
    `HasPTO` tinyint(1) NOT NULL DEFAULT '0', 
    `IsReviewer` tinyint(1) NOT NULL DEFAULT '0', 
    `ReviewerEmployeeID` int(10) unsigned DEFAULT NULL, 
    `OffshoreGroupID` int(10) unsigned DEFAULT NULL, 
    `CertificateOfInsuranceExpiration` date DEFAULT NULL, 
    `CertificateOfInsuranceNotes` longtext, 
    `WorkersCompExpiration` date DEFAULT NULL, 
    `WorkersCompNotes` longtext, 
    PRIMARY KEY (`EmployeeID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
/*!40101 SET character_set_client = @saved_cs_client */; 

-- 
-- Table structure for table `employeepayrate` 
-- 

DROP TABLE IF EXISTS `employeepayrate`; 
/*!40101 SET @saved_cs_client  = @@character_set_client */; 
/*!40101 SET character_set_client = utf8 */; 
CREATE TABLE `employeepayrate` (
    `EmployeePayRateID` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `EmployeeId` int(10) unsigned NOT NULL, 
    `StartDate` date NOT NULL, 
    `Rate` double NOT NULL, 
    PRIMARY KEY (`EmployeePayRateID`), 
    UNIQUE KEY `unq_EmployeePayRate` (`EmployeeId`,`StartDate`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
/*!40101 SET character_set_client = @saved_cs_client */; 

-- 
-- Table structure for table `projects` 
-- 

DROP TABLE IF EXISTS `projects`; 
/*!40101 SET @saved_cs_client  = @@character_set_client */; 
/*!40101 SET character_set_client = utf8 */; 
CREATE TABLE `projects` (
    `ProjectID` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `ProjectName` varchar(150) NOT NULL, 
    `ProjectDescription` longtext, 
    `ClientID` int(10) unsigned NOT NULL, 
    `ProjectBeginDate` date NOT NULL, 
    `ProjectEndDate` date NOT NULL, 
    `Active` char(1) NOT NULL, 
    `Billable` tinyint(1) NOT NULL DEFAULT '0', 
    `EngagementID` int(10) unsigned DEFAULT NULL, 
    `ClassificationID` int(10) unsigned NOT NULL DEFAULT '9', 
    `ProjectTypeID` int(10) unsigned NOT NULL DEFAULT '5', 
    PRIMARY KEY (`ProjectID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
/*!40101 SET character_set_client = @saved_cs_client */; 

-- 
-- Table structure for table `timesheetdetails` 
-- 

DROP TABLE IF EXISTS `timesheetdetails`; 
/*!40101 SET @saved_cs_client  = @@character_set_client */; 
/*!40101 SET character_set_client = utf8 */; 
CREATE TABLE `timesheetdetails` (
    `TimeCardDetailID` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `TimeCardID` int(10) unsigned NOT NULL, 
    `ProjectID` int(10) unsigned NOT NULL, 
    `BillableHours` decimal(4,2) NOT NULL, 
    `WorkDate` date NOT NULL, 
    PRIMARY KEY (`TimeCardDetailID`), 
    KEY `fk_TimesheetDetails_Project_idx` (`ProjectID`), 
    KEY `fk_TimesheetDetails_Timesheets_idx` (`TimeCardID`), 
    KEY `idx_TimesheetDetails_WorkDate` (`WorkDate`), 
    CONSTRAINT `fk_TimesheetDetails_Project` FOREIGN KEY (`ProjectID`) REFERENCES `projects` (`ProjectID`) ON DELETE NO ACTION ON UPDATE NO ACTION, 
    CONSTRAINT `fk_TimesheetDetails_Timesheets` FOREIGN KEY (`TimeCardID`) REFERENCES `timesheets` (`TimeCardID`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
/*!40101 SET character_set_client = @saved_cs_client */; 

-- 
-- Table structure for table `timesheets` 
-- 

DROP TABLE IF EXISTS `timesheets`; 
/*!40101 SET @saved_cs_client  = @@character_set_client */; 
/*!40101 SET character_set_client = utf8 */; 
CREATE TABLE `timesheets` (
    `TimeCardID` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `EmployeeID` int(10) unsigned NOT NULL, 
    `DateEntered` date NOT NULL, 
    `PPEDate` date NOT NULL, 
    PRIMARY KEY (`TimeCardID`), 
    KEY `fk_Timesheets_Employee_idx` (`EmployeeID`), 
    KEY `idx_Timsheets_PPEDate` (`PPEDate`), 
    CONSTRAINT `fk_Timesheets_Employee` FOREIGN KEY (`EmployeeID`) REFERENCES `employee` (`EmployeeID`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
/*!40101 SET character_set_client = @saved_cs_client */; 
/*!40103 SET [email protected]_TIME_ZONE */; 

/*!40101 SET [email protected]_SQL_MODE */; 
/*!40014 SET [email protected]_FOREIGN_KEY_CHECKS */; 
/*!40014 SET [email protected]_UNIQUE_CHECKS */; 
/*!40101 SET [email protected]_CHARACTER_SET_CLIENT */; 
/*!40101 SET [email protected]_CHARACTER_SET_RESULTS */; 
/*!40101 SET [email protected]_COLLATION_CONNECTION */; 
/*!40111 SET [email protected]_SQL_NOTES */; 

-- Dump completed on 2015-02-23 15:49:19 

這個樣本數據應該足夠了。

INSERT INTO `timesheet_test`.`employee` (`EmployeeID`, `FirstName`, `LastName`, `Address`, `CountryID`, `Phone1`, `Email`, `Comments`, `Status`, `Payroll`, `PartTime`, `ResourceTypeId`, `Benefits`, `HasPTO`) VALUES ('1', 'Joe', 'Somebody', '123 Fake Street', '1', '555-555-5555', '[email protected]', 'Not a real person', 'Active', '1', '0', '2', '1', '1'); 
INSERT INTO `timesheet_test`.`employee` (`EmployeeID`, `FirstName`, `LastName`, `Address`, `CountryID`, `Phone1`, `Email`, `Comments`, `Status`, `Payroll`, `PartTime`, `ResourceTypeId`, `Benefits`, `HasPTO`) VALUES ('2', 'Roger', 'Rabbit', '123 Crazy Street', '1', '111-111-1111', '[email protected]', 'Not a real person', 'Active', '1', '0', '2', '1', '1'); 

INSERT INTO `timesheet_test`.`employeepayrate` (`EmployeePayRateID`, `EmployeeId`, `StartDate`, `Rate`) VALUES ('1', '1', '2015-01-17', '20'); 
INSERT INTO `timesheet_test`.`employeepayrate` (`EmployeePayRateID`, `EmployeeId`, `StartDate`, `Rate`) VALUES ('2', '2', '2015-01-17', '25'); 
INSERT INTO `timesheet_test`.`employeepayrate` (`EmployeePayRateID`, `EmployeeId`, `StartDate`, `Rate`) VALUES ('3', '1', '2015-01-24', '50'); 

INSERT INTO `timesheet_test`.`projects` (`ProjectID`, `ProjectName`, `ProjectDescription`, `ClientID`, `ProjectBeginDate`, `ProjectEndDate`, `Active`, `Billable`, `EngagementID`, `ClassificationID`, `ProjectTypeID`) VALUES ('1', 'Project Mayhem', 'Create as much Mayhem as possible', '1', '2015-01-17', '2020-01-01', 'Y', '1', '1', '1', '1'); 

INSERT INTO `timesheet_test`.`timesheets` (`TimeCardID`, `EmployeeID`, `DateEntered`, `PPEDate`) VALUES ('1', '1', '2015-01-17', '2015-01-30'); 
INSERT INTO `timesheet_test`.`timesheets` (`TimeCardID`, `EmployeeID`, `DateEntered`, `PPEDate`) VALUES ('2', '2', '2015-01-17', '2015-01-30'); 
INSERT INTO `timesheet_test`.`timesheets` (`TimeCardID`, `EmployeeID`, `DateEntered`, `PPEDate`) VALUES ('3', '1', '2015-01-24', '2015-01-30'); 
INSERT INTO `timesheet_test`.`timesheets` (`TimeCardID`, `EmployeeID`, `DateEntered`, `PPEDate`) VALUES ('4', '2', '2015-01-24', '2015-01-30'); 

INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('1', '1', '1', '8', '2015-01-19'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('2', '1', '1', '8', '2015-01-20'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('3', '1', '1', '8', '2015-01-21'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('4', '1', '1', '8', '2015-01-22'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('5', '1', '1', '8', '2015-01-23'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('6', '2', '1', '8', '2015-01-19'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('7', '2', '1', '8', '2015-01-20'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('8', '2', '1', '8', '2015-01-21'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('9', '2', '1', '8', '2015-01-22'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('10', '2', '1', '8', '2015-01-23'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('11', '3', '1', '8', '2015-01-26'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('12', '3', '1', '8', '2015-01-27'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('13', '3', '1', '8', '2015-01-28'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('14', '3', '1', '8', '2015-01-29'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('15', '3', '1', '8', '2015-01-30'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('16', '4', '1', '8', '2015-01-26'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('17', '4', '1', '8', '2015-01-27'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('18', '4', '1', '8', '2015-01-28'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('19', '4', '1', '8', '2015-01-29'); 
INSERT INTO `timesheet_test`.`timesheetdetails` (`TimeCardDetailID`, `TimeCardID`, `ProjectID`, `BillableHours`, `WorkDate`) VALUES ('20', '4', '1', '8', '2015-01-30'); 

我對以上測試數據運行以下查詢。

SELECT 
    e.EmployeeID AS EmployeeID, 
    CONCAT(e.LastName, ', ', e.FirstName) AS Resource, 
    (
     SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td, 
      Projects p 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND p.ProjectID = td.ProjectID 
     AND p.ProjectID NOT IN (24,29,606,614,746) 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS RegularHours, 
    (
     SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td, 
      Projects p 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND p.ProjectID = td.ProjectID 
     AND (p.ProjectID = 29 OR p.ProjectID = 614) 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS PTO, 
    (
     SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td, 
      Projects p 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND p.ProjectID = td.ProjectID 
     AND p.ProjectID = 24 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS Holiday, 
    (
     SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td, 
      Projects p 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND p.ProjectID = td.ProjectID 
     AND p.ProjectID = 746 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS FloatingHoliday, 
    (
     SELECT 
      SUM(td.BillableHours) 
     FROM 
      Timesheets t, 
      TimesheetDetails td 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND td.ProjectID NOT IN (606) 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS Total, 
    (
     SELECT 
      epr.Rate 

     FROM 
      EmployeePayRate epr , 
      Timesheets t, 
      TimesheetDetails td 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND epr.EmployeeID = t.EmployeeID 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
     AND epr.StartDate <= td.WorkDate 
     ORDER BY epr.StartDate DESC 
     LIMIT 1 
    ) AS PayRate, 
    (
     SELECT 
      SUM(td.BillableHours) 
      * 
      (
       SELECT epr.Rate 
       FROM EmployeePayRate epr 
       WHERE epr.EmployeeID = t.EmployeeID 
       AND epr.StartDate <= td.WorkDate 
       AND td.ProjectID NOT IN (606) 
       ORDER BY epr.StartDate DESC 
       LIMIT 1 
      ) 
     FROM 
      Timesheets t, 
      TimesheetDetails td 
     WHERE e.EmployeeID = t.EmployeeID 
     AND t.TimeCardID = td.TimeCardID 
     AND DATE(td.WorkDate) >= DATE('2015-01-17') 
     AND DATE(td.WorkDate) <= DATE('2015-01-30') 
    ) AS GrossEarnings 

FROM 
    Employee e 
WHERE (e.EmployeeID IN (SELECT t.EmployeeID 
    FROM TimesheetDetails tsd, Timesheets t 
    WHERE tsd.BillableHours > 0 
    AND tsd.WorkDate BETWEEN '2015-01-17' AND '2015-01-30' 
    AND tsd.TimeCardID = t.TimeCardID 
    ) OR e.Status = 'Active') 
AND (e.ResourceTypeID = 2 OR e.ResourceTypeID = 4) 
GROUP BY Resource 
ORDER BY Resource ASC 

帶回以下記錄集。

EmployeeID, Resource, RegularHours, PTO, Holiday, FloatingHoliday, Total, PayRate, GrossEarnings 
'2', 'Rabbit, Roger', '80.00', NULL, NULL, NULL, '80.00', '25', '2000' 
'1', 'Somebody, Joe', '80.00', NULL, NULL, NULL, '80.00', '50', '4000' 

回答

0

讓我冷凝您使用到的東西多一點可讀性的sql開頭:

Select e.employeeid as EmployeeID 
    , Concat(e.LastName, ', ', e.FirstName) AS Resource 
    , sum(case when p.projectid not in (24,29,606,614,746) then td.BillableHours else 0 end) as RegularHours 
    , sum(case when p.projectid in (29,614) then td.BillableHours else 0 end) as PTO 
    , sum(case when p.projectid = 24 then td.BillableHours else 0 end) as Holiday 
    , sum(case when p.projectid = 746 then td.BillableHours else 0 end) as FloatingHoliday 
    , sum(case when p.projectid != 606 then td.BillableHours else 0 end) as Total 
    , EPR.Rate as PayRate 
    , sum(case when p.projectid != 606 then td.BillableHours else 0 end) * EPR.Rate as GrossEarnings 
From Employee e 
    Join Timesheets t on e.EmployeeID = t.EmployeeID 
    join TimesheetDetails td on t.TimeCardID = td.TimeCardID 
    join Projects p on p.ProjectID = td.ProjectID 
    join EmployeePayRate epr on epr.EmployeeID = e.EmployeeID 
    and epr.StartDate <= td.WorkDate 
where ((td.BillableHours > 0) 
     or (e.Status = 'Active')) 
    and td.WorkDate BETWEEN '2015-01-17' AND '2015-01-30' 
Group by e.employeeid 
    , Concat(e.LastName, ', ', e.FirstName) 
    , EPR.Rate 

如果看起來可以接受的,現在我們進入了事情的肉加入到員工的工資率。我們從1到1到多到1,這樣可以改變分組。問題是如果一個員工在一段時間內有兩個(或更多)工資率,您是否想要顯示他在每個工資率期間所做的工作細目。我發現你一週沒有做一週的工作,所以你沒有計算加班時間,所以我猜這是一份加班前的綜合報告,只是一目瞭然地估計工資,因此知道多少小時的paygrade可能並不重要。銘記想到這裏是我們如何改變連接:

join EmployeePayRate epr on epr.EmployeeID = e.EmployeeID 
    and epr.StartDate <= td.WorkDate 

如果您有payrates的開始日期和結束日期的加入改變

join EmployeePayRate epr on epr.EmployeeID = e.EmployeeID 
    and epr.StartDate <= '2015-01-17' 
    and ((epr.endDate is null) or (epr.endDate >= '2015-01-17')) 
    join TimesheetDetails td on t.TimeCardID = td.TimeCardID 
    and ((epr.EndDate is null and td.WorkDate between epr.StartDate and '2015-01-30') 
     or (epr.EndDate is not null and td.WorkDate between epr.StartDate and epr.EndDate)) 

你會注意到或聲明,我們試圖避免使用諸如isnull()這樣的函數,以便我們可以使用索引。這讓我想到下一點,如果你沒有結束日期列,事情會變得更加複雜。但是,不要寫出可能不必要的整個解決方案,讓我知道如果是這樣的話,我們會弄清楚它。

+0

不幸的是,EmployeePayRate表中沒有EndDate列。假設一旦新的PayRate發生,舊的結束。舉例來說,如果我的工資是30美元,而我有新的工資或40美元的工資,那麼在2/1之前的所有工作時間將以2/1開始,之後的所有工資都將適用於40美元,除非另有新的工資在某個時刻輸入。 – jkratz55 2015-02-24 15:09:56

+0

我跑你的第一個查詢,但它是帶回120小時喬有人,而不是80. – jkratz55 2015-02-24 15:10:34

+0

這是一個有趣的問題,我加倍檢查,我使用的項目ID與你一樣,沒有加倍或什麼,和連接也是一樣的,所以不應該有任何連接擴展。我認爲這可能是多種薪資費率,但是這包含在小組中,所以如果有多個薪酬費率,您會爲該員工獲得多個行。 試試這個,加個 CONVERT(VARCHAR(10),td.WorkDate,101) 到選擇列表和按部分分組,看看Joe Somebody是否有任何特定的日子翻倍。 – Randall 2015-02-24 16:21:21