2012-06-22 4 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 

이 아닌 쿼리를 래핑하는 것입니다 결과 집합을 얻는 유일한 방법이지만 지정된 요구 사항을 충족시키는 가장 빠른 수정 방법입니다. 우리가 사용할 수있는,

;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 

을 또는 : 우리는 수량을 얻기 위해 SELECT 목록에 상관 하위 쿼리를 사용할 수

:

는 다른 방법으로, 나는 이러한 쿼리는 해당 결과를 반환 할 것으로 예상 LEFT JOIN 연산은 UNION이 아니라 두 개의 쿼리에서 수행됩니다. (우리는 Cool_Fan_Order를 참조하는 쿼리가 외부 조인의 LEFT 쪽일 수 있다는 것을 알고 있습니다. 적어도 다른 쿼리와 같은 행을 반환한다는 것을 알고 있기 때문입니다. (기본적으로 다른 쿼리는 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

BTW : 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)가 Ordered, MAX (x.Approved)가 Approved, MAX (x.PickedUp)가 PickedUp, MAXQty) 수량으로 FROM () 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

관련 문제