Sql 组合2个查询
我正在尝试导出员工时间卡信息。出口运作良好,但我正试图将员工的小费考虑在内。员工收到的小费基于工作小时数除以特定部门的总小时数乘以小费金额。例如: 地点1有5名员工。2组 经理-没有资格获得小费 员工-有资格获得小费 我需要得到“雇员”组的总小时数,以及雇员组中雇员的总小时数 假设员工组本周有111个小时。员工的工作时间为:Sql 组合2个查询,sql,sql-server,sql-server-2008,sql-server-2005,parameters,Sql,Sql Server,Sql Server 2008,Sql Server 2005,Parameters,我正在尝试导出员工时间卡信息。出口运作良好,但我正试图将员工的小费考虑在内。员工收到的小费基于工作小时数除以特定部门的总小时数乘以小费金额。例如: 地点1有5名员工。2组 经理-没有资格获得小费 员工-有资格获得小费 我需要得到“雇员”组的总小时数,以及雇员组中雇员的总小时数 假设员工组本周有111个小时。员工的工作时间为: Jim: 22 Bob: 32 Pete: 29 Dave: 28 本周的小费是100美元 要查找每个成员的提示,我将执行以下操作: Jim's Tip: 22/111
Jim: 22
Bob: 32
Pete: 29
Dave: 28
本周的小费是100美元
要查找每个成员的提示,我将执行以下操作:
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
最后一部分是经理Tim没有资格获得小费,但需要包括在我的出口中
我可以为以下对象分别运行查询:
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”和“manager”
你会注意到它基本上是相同的查询,除了我对组使用了不同的参数……我在其中使用
@DeptList
并将其设置为“All”,使用@DeptList
并将其设置为特定组,在本例中为“Employee”,因为您只需要添加一个工会就可以了
你的最终代码
UNION
SELECT 'Tim','1','30984','40','0','$0'
您可以将结果保存在临时表中,这样您就不必反复调用表值函数。此外,还不清楚您是如何识别不符合条件的员工的,因此我猜我的解决方案中缺少该部分。如果您提供详细信息,我可以更新它 无论如何,这是一种非常简单的工作形式。请注意,我是如何连接到主表的,这样我就不必在
说明
字段上进行分组的。
这可能不会给你期望的结果,但希望它能为你指明正确的方向
更新:
我已经包含了提示资格检查,但是您的函数应该将@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
这将根据位置而变化。例如,在其他位置,我们将有3个组无法获得提示。最多可能有15名员工。这是第一个查询(t1)。您将看到将其分为两个单独的查询,但只需要“提示”“提示查询中的列。我希望tit使用lEmployeeIDhmmm链接。或者我可以打破2。使用工会。如何合并上述两个查询?从未使用unionTry使用With子句,以便您可以将其检索到临时表,然后将其过滤掉。事实上,我不喜欢union。要把剩下的几组人分出来是很困难的。。。当程序循环通过时,我已经必须按照每个位置划分特定的组。希望将这两个查询合并在一起,并且只使用第二个查询的“提示”是@DeptListTip字符串或表值参数?表值参数谁有资格和谁没有资格获得提示基于“@DeptList”。我需要工资输出包括“所有”员工(因为他们都需要支付工资)。我需要通过将ID分配给“@DeptList”来计算小费。在本例中,“1”是员工组。“全部”包括员工和经理。这有意义吗?@Shmewnix,您正在使用
@DepList
和@deplistip
调用相同的函数。我想@DepListTip
只会返回符合Tip条件的员工,而@DepList
会返回所有员工?你是对的。最后,我希望显示主查询(所有用户),然后为符合Tip条件的用户添加“Tip”列。我假设“EmployeeList”可能也需要更改为“EmployeeListTip”。我需要导出所有员工的工时,以便计算正确的正常工时和加班工时。一些员工会在一天中分成多个小组。添加多个时间段。这就是为什么必须首先导出所有小时数,然后我循环计算小费。其想法是将所有这些导出到Vb.net内部的csv中。如果我在查询端处理所有这些,那么在Vb中就不必担心了。
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