【问题标题】:Join tables on multiple conditions where rows may not have all IDs在行可能不具有所有 ID 的多个条件下连接表
【发布时间】:2015-05-12 15:21:29
【问题描述】:

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

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

事务表中的相关数据是通过以下方式找到的:

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

问题是,当我尝试 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);    

【问题讨论】:

  • 您可以发布您目前尝试过的查询吗?
  • 选择 f.ProjectKey,f.AccountCategoryKey,f.PostFiscalPeriodKey,sum(f.IncomeAmount) 作为 IncomeAmount,sum(f.ExpenseAmount) 作为 ExpenseAmount,sum(f.TransactionCount) 作为 TransactionCount,bp。金额为 BudgetAmount FROM ActualCategoryPivotAccountTypeSubAccountFact f FULL JOIN BudgetsProject bp ON f.PostFiscalPeriodKey = bp.FiscalYearPeriod 和 bp.ProjectId = f.ProjectKey 和 bp.AccountCategoryId = f.AccountCategoryKey 其中 f.PostFiscalPeriodKey = 201510 和 f.ProjectKey = 1063 按 f 分组。 ProjectKey, f.AccountCategoryKey, f.PostFiscalPeriodKey, bp.Amount
  • 以上查询给出了事务表中包含的每个 accountcategoryke​​y,但排除了预算表中不存在于事务表中的那些。

标签: sql sql-server join


【解决方案1】:

我认为,在 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

您还可以尝试使用所有可能的键构建驱动程序表,然后对其进行外部连接。不知道这将如何执行。

【讨论】:

  • 据我所知,将条件添加到 ON 子句而不是 where 会将大量无关数据从 FULL JOINing 返回到预算表。它基本上返回整个预算表的预算金额,甚至是约束之外的值。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2011-03-23
    • 1970-01-01
    • 2021-07-21
    • 2013-08-17
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 2011-08-15
    相关资源
    最近更新 更多