2012-04-02 17 views
0

表Bは計画値を保持します。表Mは実際の値を保持する。テーブルBのすべての行を見つける必要があります。実際の値(つまり結合された行)はテーブルMにありません。また、結合された行には実際の値の行が異なっています。これを実現するために、外部結合と集計...グループを組み合わせて試行していますが、テーブル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) 

HTH!

+3

あなたが(両方の理由で)返され、そうでない少なくとも1行たい行のためのいくつかのサンプルデータを表示してくださいすることができ返されたい。 –

+0

クイックフィックスは、 'SUM(M.Actual_Volume)is nullまたはSUM(M.Actual_Value)is null 'をhaving節に追加することですが、n:m関係の両辺を合計しようとしていると思います。これでデータの複製が終了します。 MとBの間のあなたのスキーマと関係についての詳細を投稿できますか? –

+0

はい、TableMへのtableBはm:mです。定義テーブルがTableX – epx

答えて

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

+0

Daniel、このようにして、正しいSELECTがSELECT句として選択されていますが、何らかの理由で最後のSELECTが正しく結合せず、 Actual_Volume&Actual_Valueフィールドの値。どのように修正するための任意の考えですか? – epx

+0

@epx「B」にIDが存在し、「M」にIDが存在しない場合、Actual_VolumeとActual_Valueはnullになります。デフォルト値が必要な場合、たとえば'ISNULL([MAlt]。[Actual_Volume]、0)'を使用し、最後のselect節の 'Actual_Value'に相当します。 –

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

問題はbとmの間で1:1ではないので、mでも行67,53,1,100を持つことができます。だから今b_id 53のために、私たちは今、未解決の計画容積1と400の未解決の計画値を持っています。なぜ私はGROUP BYを試していたのですか?SUMを持っていますが、まだありません:-( – epx

+0

一見。 – zejafo

関連する問題