2011-04-22 6 views
1

XML을 반환하는 다소 털이 많은 Stored Proc (XML은 스타일 시트로 변환되어 페이지로 인쇄 됨, 기본적으로 XML의 GridView) . 단일 행에 에만 여러 행을 집계해야하는 요구 사항이 있습니다. 특정 열의 값이 두 개의 특정 값 중 하나가 아닌 경우 (열이 집계되지 않은 경우). 사실상열에 특정 값이있는 경우 SQL의 집계/그룹 테이블 행

내가해야 할 (의사 코드) 다음

select quoteID, customerName, shippingCharges, description, /*other columns*/ 
from quotes q 
    inner join customers c on q.customerID = c.customerID 
where shipDate between @fromDate and @toDate 
for xml explicit 

if description != "Insurance" and description != "Pickup": 
    /*aggregate the rows for that quoteID into one single row 
     adding together charges and the like as needed*/ 
else: 
    /*nothing - okay to have multiple rows*/ 

내가 로직 이런 종류의 처리에 대해 이동하는 방법? 내 첫 번째 추측은 임시 테이블 (또는 CTE)에 모든 값을 넣은 다음 어떻게 든 데이터를 모두 체크하여 행을 추출하고 결합해야 하는지를 확인하는 것이지만 실제로 어떻게 행해지는지 비워 둔다. , 보통은 표시기 인 이 아닙니다. 올바른 방법은입니다.

XSL 변환 파일을 사용하는 것이 좋을까요? 내 선택은 세 가지 옵션이 제한됩니다 : 저장 프로 시저

  1. 집계가,는 XSLT에서 XSLT의 손길이 닿지 않은
  2. 집계를 남겨
  3. 이 데이터는 방법으로 달성 할 수없는 훼손되지 않은 저장 프로 시저를 남겨 현재 반환 (또는 시간이 많이 소요되는 해결 방법을 많이없이 달성 될 수 없다)

편집

내가 직면 한 문제 중 하나는 보통 레코드가 동일한 ID 필드를 가지므로 전체 레코드를 합산하기 때문에 합계가 잘못 나오는 것입니다 (필드의 합계를 계산하기 때문에 은 내가 원하지 않는 분야).

예를 들어 기록은 같은 수 있습니다 :

1234 Insurance   54.65 
1234 Shipping Charge  160.00 
1234 Some Other Charge 15.00 

을 내가 이렇게 될 최종 결과를 원하는 것 :

1234 Shipment 229.65 
1234 Insurance 229.65 
:

무슨 일이 일어나고 있는지
1234 Shipment 175.00 
1234 Insurance 54.65 

이있다

그리고 합계를 내 보냅니다.

내가 사용하고있는 전략은 ID 및 설명별로 다양한 금액과 그룹을 요약하는 "AggregateData"라는 CTE를 만드는 것이 었습니다. 위의 결과 (각 설명에 대한 합계가 있으므로 값이 두 번 나타나고 보고서에 두 번 추가되기 때문에)가 실패합니다. 내가 얻은 가장 가까운 것은 Description으로 묶지 않고 Max 함수로 묶는 것입니다 (예, 좋은 생각은 아닙니다). 이것은 나에게 정확한 합계를 주지만 설명은 정확히 반영되지 않았습니다. 일부 기록은 "보험"이어야하지만 대신 "배송"이 표시됩니다.같은 CASE 표현식이 두 번 여기에 반복되는 것을 당신은주의해야합니다

SELECT 
    customerName, 
    quoteID, 
    description = CASE 
    WHEN description IN ('Insurance', 'Pickup') THEN description 
    ELSE 'Shipment' 
    END, 
    shippingCharges = SUM(shippingCharges) 
FROM quotes q 
    INNER JOIN customers c ON q.customerID = c.customerID 
GROUP BY 
    customerName, 
    quoteID, 
    CASE 
    WHEN description IN ('Insurance', 'Pickup') THEN description 
    ELSE 'Shipment' 
    END 

:

+0

'(보험, 픽업') THEN customerID ELSE 1 END'이 (가) 'GROUP BY CASE'라고 입력 할 수 있습니까? 그룹화를 원하지 않는 경우 사용할 수있는 보장 된 고유 한 열이 있습니까? –

+0

데이터를 복제해야한다고 생각하지 않습니다. XSLT는 그렇게 할 수 있습니다. –

+0

'배송료'및 '기타 요금'설명이 '발송물'로 변환되는 방식 (규칙)은 무엇입니까? –

답변

5

가장 쉬운 방법은 두 쿼리와 조합 결과

select <columns> 
where description not in('Insurance','Pickup') 
group by <some columns) 
union all 
select <columns> 
where description in('Insurance','Pickup') 
+0

나는 보험/픽업 쿼리를 수행하는 그룹이 다음과 같이 생각한다 ...? –

+0

멋지게 작동합니다. 내 유일한 질문은 어떤 행이 함께 그룹화되었는지, 어떤 행이 다른 설명을 표시하는지 알 수있는 요구 사항 일 수 있습니다. –

+0

@Wayne M : 'IsGrouped'열을 추가 할 수 있습니다. 위의 쿼리는 다음과 같이 변경됩니다.'Select 1 as IsGrouped, ... 합집합은 모두 0을 IsGrouped로 선택합니다. ... '. –

0

이 같은 아마 뭔가를 작성하는 것입니다. 당신은 평범한 부속을 사용하여이를 방지 할 수 있습니다

SELECT 
    customerName, 
    quoteID, 
    description, 
    shippingCharges = SUM(shippingCharges) 
FROM (
    SELECT 
    customerName, 
    quoteID, 
    description = CASE 
     WHEN description IN ('Insurance', 'Pickup') THEN description 
     ELSE 'Shipment' 
    END, 
    shippingCharges = SUM(shippingCharges) 
    FROM quotes q 
    INNER JOIN customers c ON q.customerID = c.customerID 
) s 
GROUP BY 
    customerName, 
    quoteID, 
    description 

또는 CTE를 :

WITH preparedList AS (
    SELECT 
    customerName, 
    quoteID, 
    description = CASE 
     WHEN description IN ('Insurance', 'Pickup') THEN description 
     ELSE 'Shipment' 
    END, 
    shippingCharges = SUM(shippingCharges) 
    FROM quotes q 
    INNER JOIN customers c ON q.customerID = c.customerID 
) 
SELECT 
    customerName, 
    quoteID, 
    description, 
    shippingCharges = SUM(shippingCharges) 
FROM preparedList 
GROUP BY 
    customerName, 
    quoteID, 
    description 

당신은 또한 필요에 따라 다른 열을 추가 할 수 있습니다.

관련 문제