我正在尝试将“主”表Account加入三个相关表,并对每个表应用一些WHERE标准。
这是我到目前为止的查询:
SELECT Account.Name
, AnnAccs.PeriodEnd AS AnnAccsPeriodEnd
, AnnAccs.LastPeriod AS AnnAccsLastPeriod
, CorpTax.PeriodEnd AS CorpTaxPeriodEnd
, CorpTax.LastPeriod AS CorpTaxLastPeriod
, SelfAss.PeriodEnd AS SAPeriodEnd
, SelfAss.LastPeriod AS SALastPeriod
FROM dbo.Account
LEFT JOIN (SELECT MAX(new_corporationtaxactivity.new_PeriodEnd) AS PeriodEnd
, new_corporationtaxactivity.new_LastPeriod AS LastPeriod
, new_CorporationTaxActivityId AS AccId
from new_corporationtaxactivity
GROUP BY
new_CorporationTaxActivityId
, new_corporationtaxactivity.new_LastPeriod
) AS CorpTax
ON CorpTax.AccId = Account.AccountId
LEFT JOIN (SELECT MAX(new_annualaccountsactivity.new_PeriodEnd) AS PeriodEnd
, new_annualaccountsactivity.new_LastPeriod AS LastPeriod
, new_AnnualAccountsActivityId AS AccId
from new_annualaccountsactivity
GROUP BY
new_AnnualAccountsActivityId
, new_annualaccountsactivity.new_LastPeriod
) AS AnnAccs
ON AnnAccs.AccId = Account.AccountId
LEFT JOIN (SELECT MAX(new_selfassessmentactivity.new_PeriodEnd) AS PeriodEnd
, new_selfassessmentactivity.new_LastPeriod AS LastPeriod
, new_SelfAssessmentActivityId AS AccId
from new_selfassessmentactivity
GROUP BY
new_SelfAssessmentActivityId
, new_selfassessmentactivity.new_LastPeriod
) As SelfAss
ON SelfAss.AccId = Account.AccountId
WHERE ( Account.new_ClientStatus = '100000000'
OR Account.new_ClientStatus = '100000001')
AND ( AnnAccs.LastPeriod = '1'
OR CorpTax.LastPeriod = '1'
OR SelfAss.LastPeriod = '1')
帐户表格为1:*,包含三个相关表格,我想执行以下操作:对于每个帐户,检查每个相关表格中的最新/最新活动(无论是年度帐户,公司税)或者自我评估,其中可能没有,被标记为“上一期”。
例如,一个帐户可能有自我评估活动(即自我评估视图/表中的一行)而没有其他相关活动,所以我希望看到类似的内容:
AccName | AnnAccsPeriodEnd | AnnAccsLastPeriod | CorpTaxPeriodEnd | CorpTaxLastPeriod | SAPeriodEnd | SALastPeriod
AccA | null | null | null | null | 01/01/2014 | true
同样,它的年度帐户活动可能不为空,但仍未标记为“LastPeriod”:
AccName | AnnAccsPeriodEnd | AnnAccsLastPeriod | CorpTaxPeriodEnd | CorpTaxLastPeriod | SAPeriodEnd | SALastPeriod
AccA | 01/01/2014 | false | null | null | 01/01/2014 | true
因此,对于其中一个活动被标记为“LastPeriod”的每个帐户,我只想要一行(一个帐户,可能1-2个相关表的列为null,至少一个总是有数据,其中LastPeriod =真)。
上面的查询给出了看起来几乎看起来像交叉或完整联接的奇怪结果,因此每个帐户将产生3-4行。例如。
在过去的几天里,我一直在为此烦恼 - 任何帮助都会非常感激!
如果我能更详细地改进问题,请告诉我!
(感谢您的编辑!)
答案 0 :(得分:1)
如果您只想要最新一行,可以将每个子查询转换为APPLY:
SELECT Account.Name,
AnnAccs.PeriodEnd AS AnnAccsPeriodEnd,
AnnAccs.LastPeriod AS AnnAccsLastPeriod,
CorpTax.PeriodEnd AS CorpTaxPeriodEnd,
CorpTax.LastPeriod AS CorpTaxLastPeriod,
SelfAss.PeriodEnd AS SAPeriodEnd,
SelfAss.LastPeriod AS SALastPeriod
FROM dbo.Account
OUTER APPLY
( SELECT TOP 1
ca.new_PeriodEnd AS PeriodEnd,
ca.new_LastPeriod AS LastPeriod,
new_CorporationTaxActivityId AS AccId
FROM new_corporationtaxactivity ca
WHERE ca.AccId = Account.AccountId
ORDER BY ca.new_PeriodEnd DESC
) AS CorpTax
OUTER APPLY
( SELECT TOP 1 aa.new_PeriodEnd AS PeriodEnd,
aa.new_LastPeriod AS LastPeriod,
aa.new_AnnualAccountsActivityId AS AccId
FROM new_annualaccountsactivity aa
WHERE aa.new_AnnualAccountsActivityId = Account.AccountId
ORDER BY aa.new_PeriodEnd DESC
) AS AnnAccs
OUTER APPLY
( SELECT TOP 1 sa.new_PeriodEnd AS PeriodEnd,
sa.new_LastPeriod AS LastPeriod,
sa.new_SelfAssessmentActivityId AS AccId
FROM new_selfassessmentactivity sa
WHERE sa.new_SelfAssessmentActivityId = Account.AccountId
ORDER BY sa.new_PeriodEnd DESC
) As SelfAss
WHERE (Account.new_ClientStatus = '100000000' OR Account.new_ClientStatus = '100000001')
AND (AnnAccs.LastPeriod = '1' OR CorpTax.LastPeriod = '1' OR SelfAss.LastPeriod = '1')
或者您可以向每个子查询添加ROW_NUMBER()并将其限制为最高结果(RowNum = 1):
SELECT Account.Name,
AnnAccs.PeriodEnd AS AnnAccsPeriodEnd,
AnnAccs.LastPeriod AS AnnAccsLastPeriod,
CorpTax.PeriodEnd AS CorpTaxPeriodEnd,
CorpTax.LastPeriod AS CorpTaxLastPeriod,
SelfAss.PeriodEnd AS SAPeriodEnd,
SelfAss.LastPeriod AS SALastPeriod
FROM dbo.Account
LEFT JOIN
( SELECT ca.new_PeriodEnd AS PeriodEnd,
ca.new_LastPeriod AS LastPeriod,
ca.new_CorporationTaxActivityId AS AccId,
ROW_NUMBER() OVER(PARTITION BY ca.new_CorporationTaxActivityId ORDER BY ca.new_PeriodEnd DESC) AS RowNum
FROM new_corporationtaxactivity ca
) AS CorpTax
ON CorpTax.AccId = Account.AccountId
AND CorpTax.RowNum = 1
LEFT JOIN
( SELECT aa.new_PeriodEnd AS PeriodEnd,
aa.new_LastPeriod AS LastPeriod,
aa.new_AnnualAccountsActivityId AS AccId,
ROW_NUMBER() OVER(PARTITION BY aa.new_AnnualAccountsActivityId ORDER BY aa.new_PeriodEnd DESC) AS RowNum
FROM new_annualaccountsactivity aa
) AS AnnAccs
ON AnnAccs.AccId = Account.AccountId
AND AnnAccs.RowNum = 1
LEFT JOIN
( SELECT sa.new_PeriodEnd AS PeriodEnd,
sa.new_LastPeriod AS LastPeriod,
sa.new_SelfAssessmentActivityId AS AccId,
ROW_NUMBER() OVER(PARTITION BY sa.new_SelfAssessmentActivityId ORDER BY sa.new_PeriodEnd DESC) AS RowNum
FROM new_selfassessmentactivity sa
) As SelfAss
ON SelfAss.AccId = Account.AccountId
AND SelfAss.RowNum = 1
WHERE (Account.new_ClientStatus = '100000000' OR Account.new_ClientStatus = '100000001')
AND (AnnAccs.LastPeriod = '1' OR CorpTax.LastPeriod = '1' OR SelfAss.LastPeriod = '1');