在多个条件下连接表,其中行可能没有所有ID

时间:2015-05-12 15:21:30

标签: sql sql-server join

我需要为报告构建一个查询,该报告将返回所有帐户类型的预算和交易数据。问题是预算表中存在一些不在事务表中的帐户类型,反之亦然。以下是需要从每个表加入的相关信息的查询。首先,预算:

Select bp.ProjectID, bp.AccountCategoryID, bp. FiscalYearPeriod, bp.Amount AS BudgetAmount
from BudgetsProject bp
where bp.ProjectId = 1063 and bp.FiscalYearPeriod = 201510

Returns the budget table

交易表中的相关数据可通过以下方式找到:

SELECT f.ProjectKey, f.AccountCategoryKey, f.PostFiscalPeriodKey, sum(f.IncomeAmount) as IncomeAmount, sum(f.ExpenseAmount) as ExpenseAmount, sum(f.TransactionCount) as TransactionCount
FROM ActualCategoryPivotAccountTypeSubAccountFact f
Where f.ProjectKey = 1063 and f.PostFiscalPeriodKey = 201510
Group by f.ProjectKey, f.AccountCategoryKey, f.PostFiscalPeriodKey

Returns the transaction table

问题在于,当我尝试FULL JOIN表时,并非每个AccountCategoryKey值都在两个表的每一行中,所以我最终丢失了数据行。我需要在结果集中显示每个可能的Accountcategory,并且在相应的事务或预算不可用的情况下使用NULL。

我知道这个答案存在:What kind of join do I need to use to create one table from many?  但是这些表必须在匹配的Project,AccountCategory和FiscalYear字段上加入,我不知道如何将那里提出的解决方案应用于我需要加入多个条件的情况。

编辑:如果这有用,我在这里添加了重新创建表格的逻辑:

Create Table BudgetsReport (
AccountCategoryID int NOT NULL,
ProjectID int NOT NULL,
FiscalYearPeriod char(6) NOT NULL,
Amount numeric(10,2)
);

Create Table ActualCategoryPivotAccountTypeSubAccountFact (
PostFiscalPeriodKey int,
ProjectKey int,
AccountCategoryKey int,
IncomeAmount money,
ExpenseAmount money,
TransactionCount int
);

INSERT INTO BudgetsReport VALUES (1063, 5, 201510, 1626.00), (1063, 15, 201510, 8.00), (1063, 26, 201510, 1757.00), (1063, 36, 201510, 0.00), (1063, 38, 201510, 6508.00), (1063, 41, 201510, 115000.00), (1063, 42, 201510, 667.00), (1063, 43, 201510, 167.00), (1063, 51, 201510, 7289.00), (1063, 54, 201510, 21.00), (1063, 81, 201510, 138164.00), (1063, 87, 201510, 83.00), (1063, 88, 201510, 54.00), (1063, 90, 201510, 833.00);

INSERT INTO ActualCategoryPivotAccountTypeSubAccountFact VALUES (1063, 2, 201510, 0.00, 0.00, 214), (1063, 5, 201510, 0.00, 1004.42, 1), (1063, 15, 201510, 0.00, 3.92, 1), (1063, 26, 201510, 0.00, 1556.44, 10), (1063, 34, 201510, 0.00, 26.37, 1), (1063, 36, 201510, 0.00, 0.00, 19), (1063, 38, 201510, 0.00, 5764.65, 10), (1063, 41, 201510, 0.00, 131857.10, 29), (1063, 51, 201510, 0.00, 6456.27, 10), (1063, 54, 201510, 0.00, .44, 1), (1063, 87, 201510, 0.00, 28.30, 1), (1063, 90, 201510, 0.00, 545.96, 120), (1063, 93, 201510, 149945.01, 0.00, 213);    

2 个答案:

答案 0 :(得分:0)

我认为在你的where子句(WHERE f.PostFiscalPeriodKey = 201510 and f.ProjectKey = 1063)中包含这些谓词会杀死你。您可以将它们移动到on子句,但是使用完整的连接我不知道最终会出现什么。也许尝试使用带有约束的派生表,然后加入到那个。

select
...
FROM
(
select * 
from
ActualCategoryPivotAccountTypeSubAccountFact
where
PostFiscalPeriodKey = 201510
and ProjectKey = 1063) F
full join  BudgetsProject bp
on f.PostFiscalPeriodKey = bp.FiscalYearPeriod 
and bp.ProjectId = f.ProjectKey 
and bp.AccountCategoryId = f.AccountCategoryKey

您还可以尝试使用所有可能的键构建驱动程序表,然后外部连接到它。不知道这会如何表现。

答案 1 :(得分:0)

我建议使用CTE并存储可能的帐户类型和期限。然后离开加入实际和预算。

另一种选择是首先创建一个包含这些值的临时表,然后执行选择操作。