Sql server 筛选UNION中的第二条语句以防止重复结果
我走来走去,不太明白如何解决这个问题。我有两张桌子。其中一条记录中,每个员工/客户/周最多包含1条记录,列出他们在该周的估计工作小时数。这是下表中列出的“预测活动”。另一个表列出了计费活动。一个给定的员工可能在一周内为一个给定的客户拥有多个计费活动记录。表“可计费活动”中列出了这些活动 我正试图创建一个select语句,该语句将返回所有这些信息的摘要,如下面的“所需输出”表所示,但需要一些额外的聚合和筛选。输出应将预测小时数作为所有计费小时数的总和(其中批准=1)作为“计费小时数”,将所有计费小时数的总和(其中批准=0)作为“计划小时数” 我怀疑有比我所做的更直接的方法,但我已经非常接近了。我一直关注的问题是,有时在给定的一周内,员工会有预测的小时数,但没有计费小时数,反之亦然。为了帮助实现这一点,我创建了一个联盟,但我知道这个联盟不会按预期工作,因为如果该资源存在于该周的预测活动中,即使对于其他客户,它也将被排除在第二个声明之外。我尝试过几种不同的方法,但总是遇到一些障碍。如果必要的话,我可以用完全不同的方式重写这个声明。我尝试过使用完整的外部联接,使用employee表作为基础,并在此基础上构建嵌套的select语句,等等,但总是遇到一些问题 收费活动 预测活动 期望输出 当前查询-请注意,此查询将筛选到当前周Sql server 筛选UNION中的第二条语句以防止重复结果,sql-server,select,union,Sql Server,Select,Union,我走来走去,不太明白如何解决这个问题。我有两张桌子。其中一条记录中,每个员工/客户/周最多包含1条记录,列出他们在该周的估计工作小时数。这是下表中列出的“预测活动”。另一个表列出了计费活动。一个给定的员工可能在一周内为一个给定的客户拥有多个计费活动记录。表“可计费活动”中列出了这些活动 我正试图创建一个select语句,该语句将返回所有这些信息的摘要,如下面的“所需输出”表所示,但需要一些额外的聚合和筛选。输出应将预测小时数作为所有计费小时数的总和(其中批准=1)作为“计费小时数”,将所有计费小
select a.Customer,a.Resource,
sum(a.EstHours) as [Week 1 Forecast],
ISNULL(sum(c.billablehours),0) as [Week 1 Planned],
ISNULL(sum(b.BillableHours),0) as [Week 1 To Bill],
CAST(MAX(CAST(a.Onsite as INT)) as bit) as Onsite1
from ForecastedActivities a
left join BillableActivities b on (a.Customer = b.Customer) and (a.Resource = b.Resource) and (a.WeekNum = b.WeekNum) and b.Approval = 1
left join BillableActivities c on (a.Customer = c.Customer) and (a.Resource = c.Resource) and (a.WeekNum = c.WeekNum) and b.Approval = 0
where a.WeekNum = (DATEPART(week,getdate()))
group by a. Customer, a.Resource
UNION
select a.Customer,a.Resource,
0 as [Week 1 Forecast],
ISNULL(sum(c.billablehours),0) as [Week 1 Planned],
ISNULL(sum(b.BillableHours),0) as [Week 1 To Bill]
,CAST(MAX(CAST(a.BillableHours as INT)) as bit) as Onsite1
from BillableActivities a
left join BillableActivities b on (a.Customer = b.Customer) and (a.Resource = b.Resource) and (a.WeekNum = b.WeekNum) and b.Approval = 1
left join BillableActivities c on (a.Customer = c.Customer) and (a.Resource = c.Resource) and (a.WeekNum = c.WeekNum) and b.Approval = 0
where a.WeekNum = (DATEPART(week,getdate())) and
a.Resource not in (select Resource from ForecastedActivities where WeekNum = (DATEPART(week,getdate())))
group by a.Resource, a. Customer
order by Customer, Resource
如果您能提供任何帮助,我们将不胜感激。我不确定您对Onsite1专栏的尝试,因此我将其忽略。但是,这里有一个漏洞,使用完全外部连接并选择非空的客户和资源。我使用案例陈述对批准/未批准的计费小时数求和:
select
ISNULL(f.Customer, b.customer) AS Customer,
ISNULL(f.resource, b.resource) AS Resource,
ISNULL(SUM(f.EstHours) + SUM(CASE WHEN b.approval=0 THEN b.billablehours ELSE 0 END),0) AS [Week 1 Forecast],
ISNULL(sum(CASE WHEN b.approval=1 THEN b.billablehours ELSE 0 END),0) as [Week 1 To Bill]
from ForecastedActivities f
full outer join BillableActivities b
on b.customer = f.customer
and b.resource = f.resource
and b.WeekNum = f.WeekNum
where f.WeekNum = DATEPART(week,getdate())
group by ISNULL(f.Customer, b.customer), ISNULL(f.resource, b.resource)
order by ISNULL(f.Customer, b.customer), ISNULL(f.resource, b.resource)
- 首先,获取所有
——这是客户、资源、周数的列表
CTE\u Main
- 然后将你的工作时间加三次:批准、未批准、预测
- 然后将连接和左移到主CTE
WITH
CTE_Main
AS
(
SELECT
Customer
,Resource
,WeekNum
FROM BillableActivities
UNION
SELECT
Customer
,Resource
,WeekNum
FROM ForecastedActivities
)
,CTE_ToBill
AS
(
SELECT
Customer
,Resource
,WeekNum
,SUM(BillableHours) AS SumToBill
FROM BillableActivities
WHERE Approval = 1
GROUP BY
Customer
,Resource
,WeekNum
)
,CTE_Planned
AS
(
SELECT
Customer
,Resource
,WeekNum
,SUM(BillableHours) AS SumPlanned
FROM BillableActivities
WHERE Approval = 0
GROUP BY
Customer
,Resource
,WeekNum
)
,CTE_Forecast
AS
(
SELECT
Customer
,Resource
,WeekNum
,SUM(EstHours) AS SumForecast
FROM ForecastedActivities
GROUP BY
Customer
,Resource
,WeekNum
)
SELECT
CTE_Main.Customer
,CTE_Main.Resource
,CTE_Main.WeekNum
,ISNULL(CTE_Forecast.SumForecast, 0) AS SumForecast
,ISNULL(CTE_Planned.SumPlanned, 0) AS SumPlanned
,ISNULL(CTE_ToBill.SumToBill, 0) AS SumToBill
FROM
CTE_Main
LEFT JOIN CTE_Forecast ON
CTE_Forecast.Customer = CTE_Main.Customer AND
CTE_Forecast.Resource = CTE_Main.Resource AND
CTE_Forecast.WeekNum = CTE_Main.WeekNum
LEFT JOIN CTE_Planned ON
CTE_Planned.Customer = CTE_Main.Customer AND
CTE_Planned.Resource = CTE_Main.Resource AND
CTE_Planned.WeekNum = CTE_Main.WeekNum
LEFT JOIN CTE_ToBill ON
CTE_ToBill.Customer = CTE_Main.Customer AND
CTE_ToBill.Resource = CTE_Main.Resource AND
CTE_ToBill.WeekNum = CTE_Main.WeekNum
;
如果您可以为此设置sql fiddle,那就太好了。sql fiddle在您所需的输出中可用,您有
员工D
,但它不在计费活动中,也不在预测活动中。它来自哪里?在SQL FIDLE中,您有一组不同的示例数据。如果你在提琴中包含一个表格,根据提琴中包含的样本数据得出想要的结果,这会有所帮助。你现在可以忽略现场数据。查询似乎没有像我在查询中所做的那样,向下过滤到某个特定的星期。我在介绍中没有提到这一点。整个事件应该被过滤到当前周数(32)。另外,不确定您是否看到了,但这可以在sql fiddle@@LearningCurve中找到。我在介绍中没有提到这一点。然后编辑问题,而不是通过注释添加需求查询似乎没有向下过滤到特定的一周,然后只需为该周添加一个过滤器。morgb的查询与问题中给出的预期结果匹配请参见:@LearningCurve Ok-我编辑了查询以包含周数的筛选器(基于原始查询中演示的方法)。
select a.Customer,a.Resource,
sum(a.EstHours) as [Week 1 Forecast],
ISNULL(sum(c.billablehours),0) as [Week 1 Planned],
ISNULL(sum(b.BillableHours),0) as [Week 1 To Bill],
CAST(MAX(CAST(a.Onsite as INT)) as bit) as Onsite1
from ForecastedActivities a
left join BillableActivities b on (a.Customer = b.Customer) and (a.Resource = b.Resource) and (a.WeekNum = b.WeekNum) and b.Approval = 1
left join BillableActivities c on (a.Customer = c.Customer) and (a.Resource = c.Resource) and (a.WeekNum = c.WeekNum) and b.Approval = 0
where a.WeekNum = (DATEPART(week,getdate()))
group by a. Customer, a.Resource
UNION
select a.Customer,a.Resource,
0 as [Week 1 Forecast],
ISNULL(sum(c.billablehours),0) as [Week 1 Planned],
ISNULL(sum(b.BillableHours),0) as [Week 1 To Bill]
,CAST(MAX(CAST(a.BillableHours as INT)) as bit) as Onsite1
from BillableActivities a
left join BillableActivities b on (a.Customer = b.Customer) and (a.Resource = b.Resource) and (a.WeekNum = b.WeekNum) and b.Approval = 1
left join BillableActivities c on (a.Customer = c.Customer) and (a.Resource = c.Resource) and (a.WeekNum = c.WeekNum) and b.Approval = 0
where a.WeekNum = (DATEPART(week,getdate())) and
a.Resource not in (select Resource from ForecastedActivities where WeekNum = (DATEPART(week,getdate())))
group by a.Resource, a. Customer
order by Customer, Resource
select
ISNULL(f.Customer, b.customer) AS Customer,
ISNULL(f.resource, b.resource) AS Resource,
ISNULL(SUM(f.EstHours) + SUM(CASE WHEN b.approval=0 THEN b.billablehours ELSE 0 END),0) AS [Week 1 Forecast],
ISNULL(sum(CASE WHEN b.approval=1 THEN b.billablehours ELSE 0 END),0) as [Week 1 To Bill]
from ForecastedActivities f
full outer join BillableActivities b
on b.customer = f.customer
and b.resource = f.resource
and b.WeekNum = f.WeekNum
where f.WeekNum = DATEPART(week,getdate())
group by ISNULL(f.Customer, b.customer), ISNULL(f.resource, b.resource)
order by ISNULL(f.Customer, b.customer), ISNULL(f.resource, b.resource)
WITH
CTE_Main
AS
(
SELECT
Customer
,Resource
,WeekNum
FROM BillableActivities
UNION
SELECT
Customer
,Resource
,WeekNum
FROM ForecastedActivities
)
,CTE_ToBill
AS
(
SELECT
Customer
,Resource
,WeekNum
,SUM(BillableHours) AS SumToBill
FROM BillableActivities
WHERE Approval = 1
GROUP BY
Customer
,Resource
,WeekNum
)
,CTE_Planned
AS
(
SELECT
Customer
,Resource
,WeekNum
,SUM(BillableHours) AS SumPlanned
FROM BillableActivities
WHERE Approval = 0
GROUP BY
Customer
,Resource
,WeekNum
)
,CTE_Forecast
AS
(
SELECT
Customer
,Resource
,WeekNum
,SUM(EstHours) AS SumForecast
FROM ForecastedActivities
GROUP BY
Customer
,Resource
,WeekNum
)
SELECT
CTE_Main.Customer
,CTE_Main.Resource
,CTE_Main.WeekNum
,ISNULL(CTE_Forecast.SumForecast, 0) AS SumForecast
,ISNULL(CTE_Planned.SumPlanned, 0) AS SumPlanned
,ISNULL(CTE_ToBill.SumToBill, 0) AS SumToBill
FROM
CTE_Main
LEFT JOIN CTE_Forecast ON
CTE_Forecast.Customer = CTE_Main.Customer AND
CTE_Forecast.Resource = CTE_Main.Resource AND
CTE_Forecast.WeekNum = CTE_Main.WeekNum
LEFT JOIN CTE_Planned ON
CTE_Planned.Customer = CTE_Main.Customer AND
CTE_Planned.Resource = CTE_Main.Resource AND
CTE_Planned.WeekNum = CTE_Main.WeekNum
LEFT JOIN CTE_ToBill ON
CTE_ToBill.Customer = CTE_Main.Customer AND
CTE_ToBill.Resource = CTE_Main.Resource AND
CTE_ToBill.WeekNum = CTE_Main.WeekNum
;