2012-06-22 17 views
7

好的 - 我已经看过,看过并找到很多示例,但没有满足我的需要。也许我用错误的词搜索,但我可以使用你的帮助。我会尽可能详细地提供。如何从联合声明中删除重复的行

我需要生成一个报告,将两个表(或者说一个视图和一个表)的字段合并到一个报表的表中。下面是我使用的语句:

SELECT A.ConfInt, A.Conference, 
     NULL as Ordered, 
     NULL as Approved, 
     NULL as PickedUp, 
     SUM(dbo.Case_Visit_Payments.Qty) AS Qty 
FROM   dbo.Conferences as A INNER JOIN 
         dbo.Case_Table ON A.ConfInt = dbo.Case_Table.Conference_ID INNER JOIN 
         dbo.Case_Visit_Payments ON dbo.Case_Table.Case_ID = dbo.Case_Visit_Payments.Case_ID 
WHERE  (dbo.Case_Visit_Payments.Item_ID = 15 AND A.ProjectCool = 1) 
GROUP BY A.Conference, A.ConfInt 
UNION 
SELECT B.ConfInt, 
     B.Conference, 
     SUM(dbo.Cool_Fan_Order.NumberOfFansRequested) AS Ordered, 
     SUM(dbo.Cool_Fan_Order.Qty_Fans_Approved) AS Approved, 
     SUM(dbo.Cool_Fan_Order.Qty_Fans_PickedUp) AS PickedUp, 
     NULL AS Qty 
FROM   dbo.Conferences as B LEFT OUTER JOIN 
         dbo.Cool_Fan_Order ON B.ConfInt = dbo.Cool_Fan_Order.Conference_ID 
where B.ProjectCool = 1 
GROUP BY B.Conference, B.ConfInt 

,这里是结果:

4 Our Lady  NULL NULL NULL 11 
4 Our Lady  40  40  40  NULL 
7 Holy Rosary  20  20  20  NULL 
11 Little Flower NULL NULL NULL 21 
11 Little Flower 5  5  20  NULL 
19 Perpetual Help NULL NULL NULL 2 
19 Perpetual Help 20  20  20  NULL 

我强烈希望是没有重复的行,如:

4 Our Lady  40  40  40  11 
7 Holy Rosary  20  20  20  NULL 
11 Little Flower 5  5  20  21 
19 Perpetual Help 20  20  20  2 

我希望这个问题很清楚。任何建议将不胜感激。我的确标记为已回答。 :)

格雷戈里

回答

5

简单的回答是包装您的查询里面一个又一个,

SELECT ConfInt 
    , Conference 
    , SUM(Ordered) AS Ordered 
    , SUM(Approved) As Approved 
    , SUM(PickedUp) AS PickedUp 
    , SUM(Qty) AS Qty 
    FROM (

     <your UNION query here> 

    ) 
GROUP BY ConfInt, Conference 

这不是这是实现结果集的唯一方法,但它是满足特定要求的最快速解决方案。

作为替代方案,我相信这些查询将返回相同的结果:

我们可以使用相关子查询在SELECT列表以获得数量:

;WITH q AS 
     (SELECT B.ConfInt 
      , B.Conference 
      , SUM(o.NumberOfFansRequested) AS Ordered 
      , SUM(o.Qty_Fans_Approved) AS Approved 
      , SUM(o.Qty_Fans_PickedUp) AS PickedUp 
      FROM dbo.Conferences as B 
      LEFT 
      JOIN dbo.Cool_Fan_Order o ON o.Conference_ID = B.ConfInt 
     WHERE B.ProjectCool = 1 
     GROUP BY B.ConfInt, B.Conference 
    ) 
SELECT q.ConfInt 
     , q.Conference 
     , q.Ordered 
     , q.Approved 
     , q.PickedUp 
     , (SELECT SUM(v.Qty) 
      FROM dbo.Case_Table t 
      JOIN dbo.Case_Visit_Payments v ON v.Case_ID = t.Case_ID 
      WHERE t.Conference_ID = q.ConfInt 
      AND v.Item_ID = 15 
     ) AS Qty 
    FROM q 
    ORDER BY q.ConfInt, q.Conference 

或者,我们可以使用对两个查询进行LEFT JOIN操作,而不是UNION。 (我们知道引用Cool_Fan_Order的查询可以是外连接的左侧,因为我们知道它至少返回与其他查询相同数量的行(基本上,我们知道另一个查询不能返回ConfInt的值和会议不在的Cool_Fan_Order查询。)

;WITH p AS 
     (SELECT A.ConfInt 
      , A.Conference 
      , SUM(v.Qty) AS Qty 
      FROM dbo.Conferences as A 
      JOIN dbo.Case_Table t ON t.Conference_ID = A.ConfInt 
      JOIN dbo.Case_Visit_Payments v ON v.Case_ID = t.Case_ID 
     WHERE A.ProjectCool = 1 
      AND v.Item_ID = 15 
     GROUP BY A.ConfInt, A.Conference 
    ) 
    , q AS 
     (SELECT B.ConfInt 
      , B.Conference 
      , SUM(o.NumberOfFansRequested) AS Ordered 
      , SUM(o.Qty_Fans_Approved) AS Approved 
      , SUM(o.Qty_Fans_PickedUp) AS PickedUp 
      FROM dbo.Conferences as B 
      LEFT 
      JOIN dbo.Cool_Fan_Order o ON B.ConfInt = o.Conference_ID 
     WHERE B.ProjectCool = 1 
     GROUP BY B.ConfInt, B.Conference 
    ) 
SELECT q.ConfInt 
     , q.Conference 
     , q.Ordered 
     , q.Approved 
     , q.PickedUp 
     , p.Qty 
    FROM q 
    LEFT 
    JOIN p ON p.ConfInt = q.ConfInt AND p.Conference = q.Conference 
    ORDER BY q.ConfInt, q.Conference 

这三个之间选择(他们所有所有conditons下返回结果集当量),归结为可读性和可维护性和性能。在足够大的行集,这三条语句之间可能会有一些可观察到的性能差异。

+0

相关的子查询有诀窍。它工作完美。谢谢一堆。 –

+0

顺便说一句:公共表表达式在SELECT列表中与相关子查询语句不是必需的; CTE可以很容易地用一个内联视图(在FROM子句中)替换,如果这是MySQL,我们需要这么做。 – spencer7593

6

你可以用你的实际查询作为子查询,通过非聚集列使用您的非重复值和组聚合函数(Max或SUM)

SELECT ConfInt, Conference, MAX(Ordered), MAX(Approved), MAX(PickedUp), MAX(Qty) 
FROM (<your actualQuery>) 
GROUP BY ConfInt, Conference. 
+0

这个工作后,我做了一些编辑。我不得不将你的选择定义为表格,以使其发挥作用。 SELECT x.ConfInt,x.Conference,MAX(x.Ordered)as Ordered,MAX(x.Approved)as Approved,MAX(x.PickedUp)as PickedUp,MAX(x。数量)作为数量 FROM(<您的actualQuery>)x GROUP BY x.Conference,x.ConfInt –

0

我只是在第一次选择并删除联合时将联接添加到了Cool_Fan_Order。

这是否返回相同的结果?

select 
     A.ConfInt, 
     A.Conference, 
     sum(dbo.Cool_Fan_Order.NumberOfFansRequested) as Ordered, 
     sum(dbo.Cool_Fan_Order.Qty_Fans_Approved) as Approved, 
     sum(dbo.Cool_Fan_Order.Qty_Fans_PickedUp) as PickedUp, 
     sum(sub.Qty) as Qty 
    from 
     dbo.Conferences as A 
     left outer join 
     (
      select 
       c.ConfInt, 
       cvp.Qty 
      from dbo.Conferences c 
       inner join dbo.Case_Table ct 
        on a.confInt=ct.Conference_ID 
       inner join dbo.Case_Visit_Payments cvp 
        on ct.Case_ID=cvp.Case_ID 
      where cvp.Item_ID=15 
     ) sub 
      on a.ConfInt=sub.ConfInt 
     left outer join dbo.Cool_Fan_Order 
      on A.ConfInt = dbo.Cool_Fan_Order.Conference_ID 
    where 
     (
     A.ProjectCool = 1 
     ) 
    group by 
     A.Conference, 
     A.ConfInt 
+0

这不会返回相同的结果。它过滤掉只发现Case_Visit_Payments的记录。 –

+0

是的,我太懒惰了。你应该做的是将案例逻辑移到子查询中。这应该在理论上起作用。 – DForck42

+0

“理论上理论和实践没有区别,实际上存在。” - 瑜珈贝拉 – spencer7593