我正在尝试将表(员工表)加入另外两个表(员工收入和员工扣除),以显示特定类型的收入和扣除员工的金额。现在,当我的查询重复扣除时,员工有两种不同类型的收入记录,而只有一种记录用于扣除类型。员工与收入和扣减表之间存在一对多的关系。
这是我的问题:
SELECT EmployeeMaster.EmployeeNumber, FirstName, LastName, MiddleName, empEarnings.EarningCode, empEarnings.amt, empDeduc.DeductionId, empDeduc.amt
from EmployeeMaster
LEFT OUTER JOIN
(
SELECT EmployeeNumber, EarningCode, SUM(Amount) AS amt FROM EmployeeEarnings GROUP BY EmployeeNumber, EarningCode
) AS empEarnings
ON EmployeeMaster.EmployeeNumber = empEarnings.EmployeeNumber
LEFT OUTER JOIN
(
SELECT EmployeeID, DeductionID, SUM(Amount) AS amt FROM EmployeeDeduction GROUP BY EmployeeID, DeductionId
) AS empDeduc
ON EmployeeMaster.EmployeeNumber = empDeduc.EmployeeId
返回(仅样本数据)
00001 First Name Last Name EARN 1000000.0000000000000000 SSS 1000.0000000000000000
00001 First Name Last Name EARN2 1000.0000000000000000 SSS 1000.0000000000000000
00002 First Name2 Last Name2 EARN 10000.0000000000000000 SSS 100.0000000000000000
00002 First Name2 Last Name2 EARN2 10000.0000000000000000 SSS 100.0000000000000000
结果几乎正确,除了这些员工只有一个扣除类型的记录。但是,结果集会复制扣除表结果,这会导致我的ssrs报告中总扣除的总和(假设值的两倍)。
我应该如何修改我的查询以满足这些要求,还能够以如下格式生成ssrs报告:
Emp# First Name Last Name EarnType1 EarnType2 [...] DeducType1 DeducType2 [...]
#1 John Doe 100000 100000 100 100
答案 0 :(得分:1)
我会以不同的方式解决这个问题。
您需要做的是生成一份包含收入和扣除额的员工的平面列表,然后简单地获取您的报告,以便按代码对收入/扣减进行分组。
我已经整理了一个简单的脚本来执行此操作。它或多或少与你的相同(显而易见的例外是表名是变量,所以只需将它们换成真正的表名)
DECLARE @EmployeeMaster TABLE (EmployeeNumber int, FirstName varchar(30), LastName varchar(30), MiddleName varchar(30))
DECLARE @EmployeeEarnings TABLE (EmployeeNumber int, EarningCode varchar(10), Amount float)
DECLARE @EmployeeDeduction TABLE (EmployeeID int, DeductionID varchar(10), Amount float)
INSERT INTO @EmployeeMaster
VALUES (1, 'Bob', 'Smith', 'W'), (2, 'Jane', 'Jones', 'A')
INSERT INTO @EmployeeEarnings
VALUES (1, 'Earn1', 1000000), (1, 'Earn2', 1000), (2, 'Earn1', 500000), (2, 'Earn2', 500)
INSERT INTO @EmployeeDeduction
VALUES (1, 'Deduct1', 1000), (1, 'Deduct2', 800), (2, 'Deduct1', 500), (2, 'Deduct2', 200)
SELECT
emp.EmployeeNumber, FirstName, LastName, MiddleName
, amts.AmountCode, amts.amt, amts.AmountType
from @EmployeeMaster emp
LEFT OUTER JOIN
(
SELECT 'Earning' as AmountType, EmployeeNumber, EarningCode as AmountCode
, SUM(Amount) AS amt
FROM @EmployeeEarnings GROUP BY EmployeeNumber, EarningCode
UNION ALL
SELECT 'Deduction', EmployeeID, DeductionID
, SUM(Amount) AS amt FROM @EmployeeDeduction GROUP BY EmployeeID, DeductionId
) AS amts
ON emp.EmployeeNumber = amts.EmployeeNumber
我们在这里所做的就是将所有收入和扣除额合并为一套,并将其标记为任何类型(除非您希望报告将收入和扣除额保持在一起,否则实际上不需要金额类型)< / p>
这为我们提供了以下输出
EmployeeNumber FirstName LastName MiddleName AmountCode amt AmountType
1 Bob Smith W Deduct1 1000 Deduction
1 Bob Smith W Deduct2 800 Deduction
1 Bob Smith W Earn1 1000000 Earning
1 Bob Smith W Earn2 1000 Earning
2 Jane Jones A Deduct1 1000 Deduction
2 Jane Jones A Deduct2 800 Deduction
2 Jane Jones A Earn1 1000000 Earning
2 Jane Jones A Earn2 1000 Earning
然后我创建了一个简单的矩阵报告,这里是设计......
当我们运行报告时,我们得到了这个......
正如您所看到的,有两个列组,一个按类型分组(赚取/扣除),另一个按代码分组。矩阵将扩展以自动适应任意数量的收入和扣减代码。
答案 1 :(得分:0)
对以下http://sqlfiddle.com/#!6/71e8b/12使用SQL Fiddle:
我认为这是你想要的简写:
CREATE TABLE emp (
empNum INT,
fName VARCHAR(20),
lName VARCHAR(20),
mName varchar(20));
create table empEarnings(
eCode INT,
empNum INT,
earnAmount INT);
create table empDeduc(
empDedId INT,
emDedAmt INT,
empNum INT);
INSERT INTO emp (empNum, fName, lName, mName)
VALUES (1, 'a', 'ab', 'abc');
INSERT INTO empEarnings (eCode, earnAmount, empNum)
VALUES (1, 100, 1);
INSERT INTO empDeduc (empDedId, emDedAmt, empNum)
VALUES (1, 2, 1);
INSERT INTO empDeduc (empDedId, emDedAmt, empNum)
VALUES (2, 3, 1);
解答:
;With getEarnSum AS(
SELECT ee.empNum, SUM(ee.earnAmount) AS 'sumAmount' FROM empEarnings ee
LEFT OUTER JOIN empDeduc ed ON ee.empNum = ed.empNum
GROUP BY ee.empNum)
SELECT emp.fname, emp.lname, emp.mname, cte.sumAmount FROM emp
LEFT OUTER JOIN
getEarnSum cte ON emp.empNum = cte.empNum
答案 2 :(得分:0)
以垂直方式组合演绎和收益结果集。然后在SSRS中使用矩阵以水平正式显示。
CREATE TABLE #Employee (EmployeeNumber int, LastName varchar(100), FirstName varchar(100))
CREATE TABLE #Earning (EmployeeNumber int, EarningCode varchar(10), Amount money)
CREATE TABLE #Deduction (EmployeeNumber int, DeductionCode varchar(10), Amount money)
INSERT INTO #Employee (EmployeeNumber, LastName, FirstName) VALUES
(1, 'Smith', 'John'),
(2, 'Doe', 'Jane')
INSERT INTO #Earning (EmployeeNumber, EarningCode, Amount) VALUES
(1, 'EARN1', 1.11),
(1, 'EARN2', 3.33),
(1, 'EARN3', 5.55),
(1, 'EARN4', 7.77),
(2, 'EARN1', 2.22),
(2, 'EARN2', 4.44)
INSERT INTO #Deduction (EmployeeNumber, DeductionCode, Amount) VALUES
(1, 'DEDU1', 2.22),
(1, 'DEDU2', 4.44),
(2, 'DEDU1', 1.11),
(2, 'DEDU2', 3.33),
(2, 'DEDU3', 5.55),
(2, 'DEDU4', 7.77)
SELECT EMP.EmployeeNumber, EMP.FirstName, EMP.LastName, DED.DeductionCode AS 'Code', SUM(Amount) AS 'Amount'
FROM #Employee AS EMP JOIN #Deduction AS DED ON EMP.EmployeeNumber = DED.EmployeeNumber
GROUP BY EMP.EmployeeNumber, EMP.FirstName, EMP.LastName, DED.DeductionCode
UNION ALL
SELECT EMP.EmployeeNumber, EMP.FirstName, EMP.LastName, ERN.EarningCode AS 'Code', SUM(Amount) AS 'Amount'
FROM #Employee AS EMP JOIN #Earning AS ERN ON EMP.EmployeeNumber = ERN.EmployeeNumber
GROUP BY EMP.EmployeeNumber, EMP.FirstName, EMP.LastName, ERN.EarningCode
DROP TABLE #Employee
DROP TABLE #Earning
DROP TABLE #Deduction