Sql 连接两个表以获得匹配的记录和不匹配的记录

Sql 连接两个表以获得匹配的记录和不匹配的记录,sql,sql-server,Sql,Sql Server,例如,我有两张桌子 DECLARE @Employee TABLE( [EmployeeID] INT NOT NULL, [FirstName] VARCHAR(250) NOT NULL, [LastName] VARCHAR(250) NOT NULL, [Value] INT NOT NULL, [ExpenditureID] INT NOT NULL ); DECLARE @Expenditure TABLE( [ExpenditureID

例如,我有两张桌子

DECLARE @Employee TABLE( 
   [EmployeeID] INT NOT NULL, 
   [FirstName] VARCHAR(250) NOT NULL, 
   [LastName] VARCHAR(250) NOT NULL,
   [Value] INT NOT NULL,
   [ExpenditureID] INT NOT NULL
);

DECLARE @Expenditure TABLE( 
   [ExpenditureID] INT NOT NULL, 
   [Type] VARCHAR(250) NOT NULL   
);


INSERT @Expenditure ([ExpenditureID], [Type])
VALUES (1, N'Salary' ),
(2, N'Bonus')

INSERT @Employee([EmployeeID], [FirstName], [LastName], [Value], [ExpenditureID]) 
VALUES (1, N'Orlando', N'Gee', 1500, 1 ),
(2, N'Keith', N'Harris', 1000, 1),
(3, N'Keith', N'Harris', 700, 2),
(4, N'Donna', N'Carreras',2000, 1 ),
(5, N'Janet', N'Gates', 900, 1 ) 
我想得到这样的结果

FirstName | LastName | Value | Type
-----------------------------------
Orlando     Gee        0       Bonus
Orlando     Gee        1500    Salary
Keith       Harris     700     Bonus
Keith       Harris     1000    Salary
Donna       Carreras   0       Bonus
Donna       Carreras   2000    Salary
Janet       Gates      0       Bonus
Janet       Gates      900     Salary
我编写了返回相同结果的查询

SELECT p.FirstName, p.LastName, SUM(p.Value) AS Value, p.Type FROM (
    SELECT emp.EmployeeID, emp.FirstName, emp.LastName, emp.Value, exp.Type FROM @Employee AS emp
        INNER JOIN @Expenditure AS exp ON exp.ExpenditureID = emp.ExpenditureID 
    UNION ALL
    SELECT emp.EmployeeID, emp.FirstName, emp.LastName, 0, exp.Type FROM @Employee AS emp
        CROSS JOIN @Expenditure AS exp
    WHERE exp.ExpenditureID <> emp.ExpenditureID
) AS p
GROUP BY p.FirstName, p.LastName, p.Type
选择p.FirstName、p.LastName、SUM(p.Value)作为值,p.从中键入(
选择emp.EmployeeID、emp.FirstName、emp.LastName、emp.Value、exp.Type FROM@Employee AS emp
exp.expertitureId=emp.expertitureId上的内部联接@expense作为exp
联合所有
从@Employee中选择emp.emp.FirstName、emp.LastName、0、exp.Type作为emp
交叉连接@支出为exp
其中exp.exp.expertitureid emp.expertitureid
)AS p
按p.FirstName、p.LastName、p.Type分组

但我不喜欢这样。是否有另一种更有效地获得结果的解决方案?

使用
交叉联接
生成行,使用
左联接
引入值:

select n.*, e.type, coalesce(em.value, 0) as value
from (select distinct firstname, lastname from employee) n cross join
     expenditure e left join
     employee em
     on em.firstname = n.firstname and em.lastname = n.lastname and
        em.ExpenditureID = e.ExpenditureID;
聚合似乎没有必要,但如果您有多行需要合并在一起,则可能需要进行聚合。您的示例数据中没有此类示例


是一个数据小提琴。

您的命名约定非常糟糕。名为
employee
的表应为每个员工一行。您的数据模型(如图所示)应该有三个表:
员工
支出
、和
员工支出
@GordonLinoff已经创建了很多记录的表。我没有创造它。我想知道在这种情况下如何得到结果