2015-02-23 10 views
1

Je suis confronté à un problème en essayant de trouver une procédure stockée MySQL pour un rapport de paie. Auparavant, les taux de rémunération des employés ne pouvaient être modifiés qu'au début d'une période de paie. Cependant, ils peuvent maintenant changer au cours d'une période de paie et le rapport doit tenir compte des taux de rémunération variables au cours d'une période de paie. Une période de paie est de deux semaines.Procédure stockée MySQL - Calculer la rémunération avec des taux de rémunération variables

J'ai la requête suivante, qui est vraiment désordonnée, cela fonctionne mais ne tient pas compte du changement de taux de rémunération au milieu d'une période de paie.

Note: Les dates sont codées en dur comme exemple

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 

En fin de compte les colonnes du rapport devrait être. EmployeeID, LastName, FirstName, RegularHours, prise de force, Holiday, FloatingHoliday, Total et GrossEarnings.

Je ne suis pas très expérimenté avec les procédures stockées mais je pense que j'aurais besoin d'utiliser un curseur pour faire défiler chaque date et déterminer le taux de rémunération à appliquer.

Quoi qu'il en soit, ce code SQL créera la structure de données.

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

Cet exemple de données devrait suffire.

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

J'ai exécuté la requête suivante par rapport aux données de test ci-dessus.

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 

Le jeu d'enregistrements suivant est restauré.

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' 

Répondre

0

Permettez-moi de commencer par condensation SQL que vous utilisez dans quelque chose d'un peu plus lisible:

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 

Si cela semble acceptable, maintenant, nous entrons dans la viande de la question de la rejoindre à la rémunération des employés taux. Nous passons de 1 à 1 à un à 1, ce qui peut changer le groupement. La question est de savoir si un employé avait deux (ou plus) taux de rémunération au cours d'une période, voulez-vous afficher une ventilation de ce qu'il a fait pendant chacun des taux de rémunération. Je vois que vous ne faites pas une semaine à la fois, donc vous ne calculez pas les heures supplémentaires, donc je suppose qu'il s'agit d'un rapport d'aperçu avant les heures supplémentaires, destiné à un coup d'œil sur les estimations de la masse salariale. n'est pas important. portant cette pensée à l'esprit est de savoir comment nous changeons la jointure:

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

Si vous avez une date de début et de fin pour payrates la jointure des changements à

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

Vous remarquerez la ou des déclarations, nous essayons d'éviter d'utiliser des fonctions telles que isnull() pour pouvoir utiliser les index. ce qui m'amène au point suivant, si vous n'avez pas de colonne de date de fin, les choses deviennent plus compliquées. Mais au lieu d'écrire toute une solution qui peut ne pas être nécessaire, faites-moi savoir si c'est le cas et nous allons le comprendre.

+0

Malheureusement, il n'y a pas de colonne EndDate dans la table EmployeePayRate. Il est supposé qu'une fois qu'un nouveau PayRate a lieu, l'ancien se termine.Par exemple, si mon taux de salaire de 30 $ a commencé le 1/1 et j'ai un nouveau paiement ou 40 $ à partir de 2/1 toutes les heures avant 2/1 s'appliqueraient à 30 $, tout après s'appliquerait à 40 $ sauf un autre nouveau taux est entré à un moment donné. – jkratz55

+0

J'ai couru votre première requête mais elle rapporte 120 heures pour Joe Quelqu'un au lieu de 80. – jkratz55

+0

C'est un problème intéressant, j'ai revérifié et j'utilise les ID de projet comme vous, sans doubler ou quoi que ce soit, et les jointures sont également identiques, il ne devrait donc pas y avoir d'extension de jointure. Je pensais qu'il pourrait s'agir de taux de rémunération multiples, mais c'est inclus dans le groupe, donc s'il y avait plusieurs taux de rémunération, vous obtiendriez plusieurs lignes pour l'employé. Essayez ceci, ajoutez CONVERT (VARCHAR (10), td.WorkDate, 101) À la liste de sélection et le groupe par section, et de voir si Joe Quelqu'un a des jours particuliers qui sont doublés. – Randall