【发布时间】:2012-04-16 00:42:54
【问题描述】:
表 B 保存计划值。表 M 保存实际值。我需要找到表 B 中的所有行,其中表 M 中没有实际值(即连接)行,或者连接行具有不同的总实际值行。我正在尝试结合使用外连接和 sum ... group by 来实现这一点,但它不起作用,因为表 B 中的“孤儿”没有被返回。
我的查询是:-
SELECT B.Id, B.Date, b.Ref,SUM(M.Actual_Volume), SUM(B.Planned_Volume),
SUM(M.Actual_Value),SUM(B.Planned_Value)
FROM
TableB B
left JOIN TableM M on M.Id = B.Id
inner JOIN TableX on TableX.FieldX = B.FieldX
WHERE TableX.FieldY = (SELECT T.FieldY from TableX T where T.FieldX = 408344)
AND TableX.FieldZ = (SELECT T1.FieldZ from TableX T1 where T1.FieldX = 408344)
group by B.Id, B.Date, B.Ref
having SUM(M.Actual_Volume) <> SUM(B.Planned_Volume)
OR SUM(M.Actual_Value) <> SUM(B.Planned_Value)
order by b.Id
如果我使用 = 而不是 来比较实际值和计划值,我会得到加入的行,但我需要实际值不等于计划值的行,或者有计划但没有实际值的行。
谢谢!
Table B
Id planned_vol planned val
19 2 350
28 1 100
53 3 650
61 1 50
Table M
M.Id B.Id actual_vol actual_val
58 19 2 350
65 28 1 100
66 53 1 150
所以查询应该返回,
B.Id
53 (because planned_vol <> actual_vol and planned_val <> actual_val)
61 (because B.Id 61 is not in table M)
hth!
【问题讨论】:
-
能否请您显示一些您想要返回的行的示例数据(出于这两个原因)和至少一个您不想返回的行。
-
快速解决方法是将
SUM(M.Actual_Volume) is null or SUM(M.Actual_Value) is null添加到有子句中,但我认为您正在尝试对 n:m 关系的双方求和。这将导致数据重复。您能否发布更多关于您的架构以及 M 和 B 之间关系的信息? -
是的,tableB 到 TableM 是 m:m 因为定义表是 TableX
-
我认为您的
WHERE子句可以替换为此连接:INNER JOIN TableX T ON TableX.FieldY = T.FieldY AND TableX.FieldZ = T.FieldZ AND T.FieldX = 408344(或T.FieldX = 408344可以移动到WHERE)。
标签: sql-server group-by outer-join having