2012-04-02 34 views
0

表B包含計劃值。表M保存實際值。我需要查找表B中的所有行,其中表M中沒有實際值(即已連接)的行,或者連接的行具有不同的總實際值行。我正在嘗試外部連接和總和... group by的組合來實現此目的,但它不起作用,因爲表B中的'孤兒'沒有被返回。具有左連接的SQL Server /具有總和/組編號

我的查詢是: -

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) 

心連心!

+3

能否請您顯示行,你想退回(由於這兩個原因),你不一些示例數據和至少一個排想要返回。 – 2012-04-02 10:50:16

+0

快速修復將添加'SUM(M.Actual_Volume)爲null或SUM(M.Actual_Value)爲null'的子句,但我認爲你試圖對n:m關係的兩邊進行求和。這將以數據重複結束。你能發佈更多關於你的模式和M和B之間的關係嗎? – 2012-04-02 11:07:00

+0

是的,tableB到TableM是m:m,因爲定義表是tableX – epx 2012-04-02 11:14:22

回答

1

這是未經測試的,但我認爲您需要將具有要求移動到左外部連接要求。使用CTE(即,您需要使用SQL Server 2005或更高版本才能運行)是實現此目的的一種方法。

您的having子句迫使SQL Server將B-M連接視爲內連接。可能有一種替代方法不使用在所有正確位置檢查NULL的CTE。但我更喜歡分而治之的方法。

WITH 
[BAlt] AS 
(
    SELECT 
     [B].[Id], 
     [B].[Date], 
     [B].[Ref], 
     SUM([B].[Planned_Volume]) AS [Planned_Volume], 
     SUM([B].[Planned_Value]) AS [Planned_Value], 
    FROM [TableB] AS [B] 
     INNER JOIN [TableX] AS [X1] ON [X1].[FieldX] = [B].[FieldX] 
      AND [X1].[FieldY] = 
      (
       SELECT 
        [X2].[FieldY] 
       FROM [TableX] AS [X2] 
       WHERE [X2].[FieldX] = 408344 
      ) 
      AND [X1].[FieldZ] = 
      (
       SELECT 
        [X3].[FieldZ] 
       FROM [TableX] AS [X2] 
       WHERE [X3].[FieldX] = 408344 
      ) 
    GROUP BY 
     [B].[Id], 
     [B].[Date], 
     [B].[Ref] 
), 
[MAlt] AS 
(
    SELECT 
     [M].[Id], 
     SUM([M].[Actual_Volume]) AS [Actual_Volume], 
     SUM([M].[Actual_Value]) AS [Actual_Value] 
    FROM [M] 
    GROUP BY 
     [M].[Id] 
) 
SELECT 
    [BAlt].[Id], 
    [BAlt].[Date], 
    [BAlt].[Ref], 
    [BAlt].[Planned_Volume], 
    [BAlt].[Planned_Value], 
    [MAlt].[Actual_Volume], 
    [MAlt].[Actual_Value] 
FROM [BAlt] 
    LEFT OUTER JOIN [MAlt] ON [MAlt].[Id] = [BAlt].[Id] 
     AND 
     (
      [MAlt].[Actual_Volume] <> [BAlt].[Planned_Volume] 
       OR [MAlt].[Actual_Value] <> [BAlt].[Planned_Value] 
     ) 
ORDER BY 
    [BAlt].[Id] 
+0

我正在使用SQL Server 2005 9.00.1399.06,所以我會給出這個 – epx 2012-04-02 11:20:53

+0

Daniel,試試這種方式,正確的集合被選中爲AS SELECT子句,但由於某種原因,最終的SELECT沒有正確連接並返回NULL爲Actual_Volume&Actual_Value字段。有關如何解決的任何想法? – epx 2012-04-03 10:29:01

+0

@epx在「B」中存在ID但不在「M」中的情況下,Actual_Volume和Actual_Value將爲空。如果你想要一個默認值,例如零,在最後的select子句中使用'ISNULL([MAlt]。[Actual_Volume],0)'和'Actual_Value'的等價物。 – 2012-04-03 12:37:46

0

我真不明白一個問題:

create table b 
    ( B_id int 
     ,PlannedVolume int 
     ,PlannedValue int 
    ) 

    create table M 
    ( M_id int 
     ,B_id int 
     ,ActualVolume int 
     ,ActualValue int 
    ) 

    insert b (b_id, PlannedVolume, PlannedValue) 
    values (19, 2, 350), 
     (28, 1, 100), 
     (53, 3, 650), 
     (61, 1, 50) 

    insert m (m_id, b_id, ActualVolume, ActualValue) 
    values (58, 19, 2, 350), 
     (65, 28, 1, 100), 
     (66, 53, 1, 150), 
     (67, 53, 1, 100) 

    select b.b_id 
    from b 
    left join 
    ( select b_id 
      ,sum(ActualVolume) as ActualVolume 
      ,sum(ActualValue) as ActualValue 
     from m 
     group by b_id 
    ) m  
    on m.b_id = b.b_id 
    where 
    m.b_id is null 
    or 
    (m.ActualValue <> b.PlannedValue and m.ActualVolume <> b.PlannedVolume) 
+0

問題是它不是1:1之間的B和M,所以在M你也可以有行67,53,1,100。因此,現在對於b_id 53,我們現在有一個未完成的planned_volume爲1和未完成的planned_value爲400,這就是爲什麼我試圖使用GROUP BY ...具有SUM,但它還沒有:-( – epx 2012-04-03 09:34:09

+0

我更新了評論。看看。 – zejafo 2012-04-03 18:24:53