sql - 将一个表连接到另外两个表

时间:2017-12-09 15:36:25

标签: sql-server reporting-services

我正在尝试将表(员工表)加入另外两个表(员工收入和员工扣除),以显示特定类型的收入和扣除员工的金额。现在,当我的查询重复扣除时,员工有两种不同类型的收入记录,而只有一种记录用于扣除类型。员工与收入和扣减表之间存在一对多的关系。

这是我的问题:

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     

3 个答案:

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

然后我创建了一个简单的矩阵报告,这里是设计......

enter image description here

当我们运行报告时,我们得到了这个......

enter image description here

正如您所看到的,有两个列组,一个按类型分组(赚取/扣除),另一个按代码分组。矩阵将扩展以自动适应任意数量的收入和扣减代码。

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