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

Sql server sql-将一个表连接到另外两个表,sql-server,reporting-services,Sql Server,Reporting Services,我试图将一个表(employee表)与另外两个表(employee earnings和employee Decreations)连接起来,以显示特定类型的收入和员工扣除额的金额。现在,当我的查询复制扣减时,员工有两种不同收入类型的记录,只有一种扣减类型的记录。员工与收入表和扣除表都有一对多关系 我的问题是: SELECT EmployeeMaster.EmployeeNumber, FirstName, LastName, MiddleName, empEarnings.EarningCode,

我试图将一个表(employee表)与另外两个表(employee earnings和employee Decreations)连接起来,以显示特定类型的收入和员工扣除额的金额。现在,当我的查询复制扣减时,员工有两种不同收入类型的记录,只有一种扣减类型的记录。员工与收入表和扣除表都有一对多关系

我的问题是:

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
返回(仅样本数据)

结果几乎正确,但这些员工只有一个扣除类型的记录。但是,结果集与扣除表结果重复,从而导致我的ssrs报告中总扣除额的总和错误(假定值的两倍)

我应该如何修改查询以满足这些要求,并能够以如下格式生成ssrs报告:

Emp# First Name Last Name EarnType1 EarnType2 [...] DeducType1 DeducType2 [...]
#1    John        Doe       100000    100000        100        100     

使用SQL FIDLE进行以下操作:

我认为这是你想要的东西的简写:

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

以垂直方式组合扣减和收益结果集。然后使用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

我会换一种方式来做

您需要做的是生成一个包含收入和扣除额的员工的平面列表,然后简单地让您的报告按代码对收入/扣除额进行分组

我编写了一个简单的脚本来实现这一点。它和您的差不多(明显的例外是表名是变量,所以只需将它们替换为真正的表名)

我们在这里所做的就是将所有收入和扣减合并到一个集合中,并将每个集合标记为任何类型(金额类型实际上是不必要的,除非您希望您的报告将收入和扣减集中在一起)

这为我们提供了以下输出

        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
然后我创建了一个简单的矩阵报告,下面是设计

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


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

每个员工只有两种收入类型和两种扣减类型?不,一个员工可以有很多。您想要的结果仅显示2。所以现在你说你想要的结果实际上可以有无限多的收入类型和扣除类型?这只是一个样本数据。至于水平格式,我相信我可以用ssrs报告服务来完成。@FriencyFernandez说得不错。在SRRS中使用矩阵将生成带有查询的垂直结果集的水平格式。我只需要一个结果集,可以让我产生正确的输出。谢谢你的回答谢谢但cte不知何故没有返回所需的输出,因为它只返回收益,而不返回扣除额,也不按收益类型分组。酷。我要试试这个!非常感谢。我一直在那里尝试联盟,但我无法找出如何相应地将其分组。很高兴能提供帮助,我们都遇到过无法找出非常简单的事情的情况。我已经做了这么多年了,这只是经验!还有一件事!!我刚刚注意到代码中有一个潜在的bug。您需要将
UNION
更改为
UNION ALL
,以防您有两个相同的收入或扣除项目,因为
UNION
将删除重复项,而
UNION ALL
将保留重复项。我已经更新了答案我有个问题。你能告诉我,我怎样才能把这两个单独的合计列出来吗?
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
        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