结合2个查询

时间:2014-06-05 18:57:21

标签: sql sql-server sql-server-2008 sql-server-2005 parameters

我正在尝试导出员工时间卡信息。出口工作正常,但我试图考虑员工的小费。员工收到的提示是根据工作小时数除以特定部门中的小时数乘以小费金额。例如:

位置1有5名员工。 2组

经理 - 不符合提示 员工 - 有资格获得提示

我需要获取“员工”组的总小时数以及员工组中员工的总小时数。

让我们说员工集团本周有111个小时。而且员工的工作时间是:

Jim: 22
Bob: 32
Pete: 29
Dave: 28

本周的提示是100.00美元

要查找每个成员提示,我会这样做:

Jim's Tip: 22/111 * 100 = $19.82
Bob's Tip: 32/111 * 100 = $28.83
Pete's Tip: 29/111 * 100 = $26.13
Dave's Tip: 28/111 * 100 = $25.23

最后一部分是经理蒂姆,没有资格获得提示,但需要包含在我的导出中。

我可以让查询单独运行:

1) to run for just the groups eligible for tips and calculate the tip
2) to run for all employees leaving tip out.

以下是我得到的输出:

Name   Location   OtherNumber   RegHours   OT Hours   TIP
Jim's    1           12345         22          0    $19.82
Bob's    1           12395         32          0    $28.83
Pete's   1           31654         29          0    $26.13
Dave's   1           03948         28          0    $25.23

这是我应该得到的输出:

Name   Location   OtherNumber   RegHours   OT Hours   TIP
Tim      1           30984         40          0    $0
Jim's    1           12345         22          0    $19.82
Bob's    1           12395         32          0    $28.83
Pete's   1           31654         29          0    $26.13
Dave's   1           03948         28          0    $25.23

这是我的代码:

获取“所有”员工的代码

SELECT        ftc.sFirstName + ' ' + ftc.sLastName AS sName, Account.sLocationDesc, Employees.sOtherNumber, SUM(ftc.RegHours) AS RegHours, SUM(ftc.OTHours) 
                         AS OTHours
FROM            dbo.fTimeCard(@StartDate, @EndDate, @DeptList, @iActive, @EmployeeList) AS ftc LEFT OUTER JOIN
                         Employees ON ftc.lEmployeeID = Employees.lEmployeeID LEFT OUTER JOIN
                         Account ON
                             (SELECT        CASE WHEN Employees.lLocationID IS NULL THEN 1 ELSE Employees.lLocationID END AS Expr1
                               FROM            Employees
                               WHERE        (lEmployeeID = ftc.lEmployeeID)) = Account.lLocationID
WHERE        (ftc.RegHours > 0) AND (ftc.RegHours IS NOT NULL)
GROUP BY Account.sLocationDesc, Employees.sOtherNumber, ftc.lEmployeeID, ftc.sLastName, ftc.sFirstName

以下是我的代码,以找出提示,以及每个员工应从符合条件的群体中获得多少:

SELECT        t3.sName, t3.TotalHours, t3.TotalHours / t4.TotalDepartmentHours * @TIP AS Tip
FROM            (SELECT        ftc.sFirstName + ' ' + ftc.sLastName AS sName, SUM(ftc.RegHours) + SUM(ftc.OTHours) AS TotalHours, ftc.lEmployeeID
                          FROM            dbo.fTimeCard(@StartDate, @EndDate, @DeptListTip, @iActive, @EmployeeList) AS ftc LEFT OUTER JOIN
                                                    Employees ON ftc.lEmployeeID = Employees.lEmployeeID LEFT OUTER JOIN
                                                    Account ON
                                                        (SELECT        CASE WHEN Employees.lLocationID IS NULL THEN 1 ELSE Employees.lLocationID END AS Expr1
                                                          FROM            Employees
                                                          WHERE        (lEmployeeID = ftc.lEmployeeID)) = Account.lLocationID
                          WHERE        (ftc.RegHours > 0) AND (ftc.RegHours IS NOT NULL)
                          GROUP BY ftc.lEmployeeID, ftc.sLastName, ftc.sFirstName) AS t3 CROSS JOIN
                             (SELECT        SUM(ftc.RegHours) + SUM(ftc.OTHours) AS TotalDepartmentHours
                               FROM            dbo.fTimeCard(@StartDate, @EndDate, @DeptListTip, @iActive, @EmployeeList) AS ftc LEFT OUTER JOIN
                                                         Employees AS Employees_1 ON ftc.lEmployeeID = Employees_1.lEmployeeID LEFT OUTER JOIN
                                                         Account AS Account_1 ON
                                                             (SELECT        CASE WHEN Employees.lLocationID IS NULL THEN 1 ELSE Employees.lLocationID END AS Expr1
                                                               FROM            Employees
                                                               WHERE        (lEmployeeID = ftc.lEmployeeID)) = Account_1.lLocationID
                               WHERE        (ftc.RegHours > 0) AND (ftc.RegHours IS NOT NULL)) AS t4

这是我的查询结合两者的输出不包括“Tim”经理“

SELECT        t1.sName, t1.sLocationDesc, t1.sOtherNumber, t1.RegHours, t1.OTHours, t2.Tip
FROM            (SELECT        ftc.sFirstName + ' ' + ftc.sLastName AS sName, Account.sLocationDesc, Employees.sOtherNumber, SUM(ftc.RegHours) AS RegHours, SUM(ftc.OTHours) 
                                                    AS OTHours, ftc.lEmployeeID
                          FROM            dbo.fTimeCard(@StartDate, @EndDate, @DeptList, @iActive, @EmployeeList) AS ftc LEFT OUTER JOIN
                                                    Employees ON ftc.lEmployeeID = Employees.lEmployeeID LEFT OUTER JOIN
                                                    Account ON
                                                        (SELECT        CASE WHEN Employees.lLocationID IS NULL THEN 1 ELSE Employees.lLocationID END AS Expr1
                                                          FROM            Employees
                                                          WHERE        (lEmployeeID = ftc.lEmployeeID)) = Account.lLocationID
                          WHERE        (ftc.RegHours > 0) AND (ftc.RegHours IS NOT NULL)
                          GROUP BY Account.sLocationDesc, Employees.sOtherNumber, ftc.lEmployeeID, ftc.sLastName, ftc.sFirstName) AS t1 INNER JOIN
                             (SELECT        t3.sName, t3.TotalHours, t3.TotalHours / t4.TotalDepartmentHours * @TIP AS Tip, t3.lEmployeeID
                               FROM            (SELECT        ftc.sFirstName + ' ' + ftc.sLastName AS sName, SUM(ftc.RegHours) + SUM(ftc.OTHours) AS TotalHours, ftc.lEmployeeID
                                                         FROM            dbo.fTimeCard(@StartDate, @EndDate, @DeptListTip, @iActive, @EmployeeList) AS ftc LEFT OUTER JOIN
                                                                                   Employees AS Employees_2 ON ftc.lEmployeeID = Employees_2.lEmployeeID LEFT OUTER JOIN
                                                                                   Account AS Account_2 ON
                                                                                       (SELECT        CASE WHEN Employees.lLocationID IS NULL THEN 1 ELSE Employees.lLocationID END AS Expr1
                                                                                         FROM            Employees
                                                                                         WHERE        (lEmployeeID = ftc.lEmployeeID)) = Account_2.lLocationID
                                                         WHERE        (ftc.RegHours > 0) AND (ftc.RegHours IS NOT NULL)
                                                         GROUP BY ftc.lEmployeeID, ftc.sLastName, ftc.sFirstName) AS t3 CROSS JOIN
                                                             (SELECT        SUM(ftc.RegHours) + SUM(ftc.OTHours) AS TotalDepartmentHours
                                                               FROM            dbo.fTimeCard(@StartDate, @EndDate, @DeptListTip, @iActive, @EmployeeList) AS ftc LEFT OUTER JOIN
                                                                                         Employees AS Employees_1 ON ftc.lEmployeeID = Employees_1.lEmployeeID LEFT OUTER JOIN
                                                                                         Account AS Account_1 ON
                                                                                             (SELECT        CASE WHEN Employees.lLocationID IS NULL THEN 1 ELSE Employees.lLocationID END AS Expr1
                                                                                               FROM            Employees
                                                                                               WHERE        (lEmployeeID = ftc.lEmployeeID)) = Account_1.lLocationID
                                                               WHERE        (ftc.RegHours > 0) AND (ftc.RegHours IS NOT NULL)) AS t4) AS t2 ON t1.lEmployeeID = t2.lEmployeeID

你会注意到它基本上是相同的查询,除了我为组使用了不同的参数...我在一个中使用@DeptList并将其设置为“全部”,并使用@DeptListTip和将其设置为特定组,在本例中为“Employee”

2 个答案:

答案 0 :(得分:1)

由于您只对管理员数据有疑问,您只需要添加一个工会。

即。你的最终代码

UNION
SELECT 'Tim','1','30984','40','0','$0'

答案 1 :(得分:0)

您可以将结果保存在临时表中,这样就不必再次调用表值函数。此外,您不清楚如何识别他/她不符合资格的员工,因此我认为我的解决方案中缺少该部分。如果您向我提供详细信息,我可以更新。

无论如何,这是一种非常简化的工作形式。 请注意我如何加入主表格,以便我不必在Group By字段上执行Description

这可能无法为您提供所需的结果,但希望它能为您指明正确的方向。

<强>更新 我已经包含了Tip Eligibility检查,但是你的函数应该返回@DepList作为表字段,这样我们就可以在查询级别上进行过滤,这将保存函数调用2次。

DECLARE @tblfTimeCard table(lEmployeeID int, TotalRegHours int, TotalOTHours int, HasTip bit)

-- first we will get all the data and do the basic summing here
-- you are also picking sFirstName and sLastName from Table Valued function
-- while I think same fields can be extracted from Employee master
-- therefore, we should only return the lEmployeeID from TVF
INSERT INTO @tblfTimeCard(lEmployeeID, TotalRegHours, TotalOTHours, HasTip)
    SELECT    lEmployeeiD, SUM(ftc.RegHours) AS TotalRegHours, SUM(ftc.OTHours) AS TotalOTHours, 0 AS HasTip
    FROM    dbo.fTimeCard(@StartDate, @EndDate, @DeptList, @iActive, @EmployeeList) AS ftc 
    WHERE      (ftc.RegHours > 0) AND (ftc.RegHours IS NOT NULL)
    GROUP BY lEmployeeID

-- set HasTip flag for the Employees who are eligible for Tip
UPDATE 
    SET HasTip = 1
FROM    @tblfTimeCard AS F
WHERE    
    Exists(
        SELECT    1
        FROM    dbo.fTimeCard(@StartDate, @EndDate, @DeptListTip, @iActive, @EmployeeList) AS ftc 
        WHERE      ftc.lEmployeeID = F.lEmployeeID
                (ftc.RegHours > 0) AND (ftc.RegHours IS NOT NULL)
    )

SELECT    EDT.lEmployeeID, EDT.TotalRegHours, EDT.TotalOTHours,
        CASE WHEN EDT.HasTip = 1 THEN 
            (EDT.TotalRegHours + EDT.TotalOTHours) / EDT.TotalDepartmentHours * @TIP 
        ELSE
            0
        END AS Tip,
        E.sFirstName + ' ' + E.sLastName AS sName,
        A.sLocationDesc
FROM    (
        SELECT    lEmployeeID, f.TotalRegHours, f.TotalOTHours,
                (
                SELECT     SUM(TotalRegHours, TotalOTHours)
                FROM    @tblfTimeCard
                -- TO DO: here the SUM is happening on whole @tblfTimeCard, while you may
                -- want to group for the particular Group, so you may need to put a filter 
                -- something like
                -- WHERE GroupID = f.GroupID
                ) AS TotalDepartmentHours,
                f.HasTip
        FROM    @tblfTimeCard AS f
        ) AS EDT     -- Employee with Department Totals
        LEFT OUTER JOIN Employees AS E ON EDT.lEmployeeID = EDT.lEmployeeID
        LEFT OUTER JOIN Accounts AS A ON ISNULL(E.lLocationID, 1) = A.lLocationID