我有4个表,我试图从中获取数据,但我的join语句返回null。我尝试了完整的,左右连接但没有成功。 Blow我提供了我的代码和图表,返回null值的表是ChannelData表。我试图从这张表中加总Vvalue:
DECLARE @bp varchar(4)
DECLARE @priority varchar(2)
DECLARE @startDate datetime
DECLARE @endDate datetime
SET @bp = 1710
SET @priority = 2
SET @endDate = (SELECT EndDate FROM BillingPeriod WHERE BillingPeriodClass_ID = 1 AND CODE = @BP)
SET @startDate = (SELECT EndDate FROM BillingPeriod WHERE BillingPeriodClass_ID = 1 AND CODE = @BP -1 )
SET @startDate = dateadd(minute, 1, @startDate)
SELECT CGS.Description,
CD.VValue, DI.Margin, @priority AS PRIORITY
FROM DataIntegrity AS DI
FULL JOIN CGS AS CGS ON CGS.ID = DI.CGS_ID_1 OR CGS.ID = DI.CGS_ID_2
LEFT JOIN ChannelParameter AS CP ON CP.ID = CGS.ID
LEFT JOIN ChannelData AS CD ON CP.ID = CD.ID AND DI.CGS_ID_1 = CD.ID AND DI.CGS_ID_2 = CD.ID
where DI.Priority = @priority
group by CGS.Description, CD.VValue, DI.Margin
结果
db_diagram
另一个例子,我在尝试此查询时,在包含Report表而不是DI表时获取空值:
SELECT SUM(CD.VValue), CGS.Description,
SUM(CD.VValue)
FROM CGS AS CGS
FULL JOIN ChannelParameter AS CP ON CP.ID = CGS.ID
FULL JOIN ChannelData AS CD ON CP.ID = CD.ID
FULL JOIN Report AS R on R.CGS_ID = CGS.ID
where -- CD.DDate BETWEEN @startDate AND @endDate
r.Description = 'rEGION EP'
group by CGS.Description, CD.VValue'
答案 0 :(得分:1)
我猜这个问题出现在加入中:
LEFT JOIN ChannelData AS CD ON CP.ID = CD.ID AND DI.CGS_ID_1 = CD.ID AND DI.CGS_ID_2 = CD.ID
除此之外,您在CGS_ID_1 OR CGS_ID_2上使用了联接,在本节中,您使用 AND 进行此操作。这是对的吗?
CP.ID = CD.ID看起来也很可疑。它看起来像是从主键到主键的连接,而不是外键的主键。
答案 1 :(得分:0)
有时,合适地加入表格不是解决方案。首先,通常建议甚至必须首先聚合并加入聚合,而不是先加入表并聚合。
然后,当我们只想检查表中的值是否存在时,我们通常希望将其作为WHERE
子句中的条件,而不是连接中的条件。
有时我们希望将数据集与UNION ALL
(或有时与UNION
)合并。
第一个查询:每个CGS,边距和优先级的vvallue总和。好吧,CGS可以有多个边距和优先级,所以我们必须先找到它们。由于该表具有CGS_ID_1和CGS_ID_2,我们将使用UNION
以获得每个CGS的边距和优先级。然后,vvalue与保证金和优先级无关;它只是每个CGS的总和,所以它将在结果中重复。
select cgs.description, di.margin, di.priority, coalesce(sum_vvalue, 0) as total
from cgs
join
(
select cgs_id_1 as cgs_id, margin, priority from dataintegrity
union
select cgs_id_1 as cgs_id, margin, priority from dataintegrity
) di on di.cgs_id = cgs.id and di.priority = @priority
left join
(
select id as cgs_id, sum(vvalue) as sum_vvalue
from channeldata
group by id
) cd on cd.cgs_id = cgs.id
order by cgs.description, di.margin, di.priority;
Secons查询:某个区域的每个CGS的vvallue总和。每个CGS可能有很多报告,我们必须在所需区域找到所有带有报告的CGS。这只是一次查询,应该使用IN
或EXISTS
。
select cgs.description, coalesce(sum_vvalue, 0) as total
from cgs
left join
(
select id as cgs_id, sum(vvalue) as sum_vvalue
from channeldata
group by id
) cd on cd.cgs_id = di.cgs_id
where cgs.id in (select cgs_id from report where description = 'REGION EP')
order by cgs.description;