2014-09-05 4 views
0

누군가가 나를 도와 줄 수 있습니다.다중 부분 합계가있는 SQL 쿼리

SQL 쿼리에서 부분합을 사용하려고하지만 다른 열로는 표시하려고하지 않습니다.

내가 얻는 결과와 설명과

페이지의 스크린 샷

Screenshot

이 쿼리는 내가 가지고있다 지금까지

SELECT 
    ar.Person_Id AS 'Id', 
    pa.Serial_Number, 
    ar.Family_Name + ', '+ar.First_Name AS 'Name', 
    CASE WHEN ar.Line_Type = 'A' THEN 'Activity: '+ar.Item_Name ELSE 'Hotel: '+ar.Item_Name END AS 'Description', 
    CAST(IsNull(ar.Old_Amount_Excl_VAT,0) AS DECIMAL(10,2)) AS 'Amount Excl VAT', 
    CAST(IsNull(ar.Old_Amount_Incl_VAT,0) AS DECIMAL(10,2)) AS 'Amount Incl VAT', 
    CAST(IsNull(ar.Old_Amount_Incl_VAT,0) - IsNull(ar.Old_Amount_Excl_VAT,0) AS DECIMAL(10,2)) AS 'VAT Amount', 
    p.Currency_Code, 
    ( 
    SELECT TOP 1 pt.Payment_Type + ' ' + pt.Description AS Payment_Type FROM PaymentsPerPerson ppp 
    LEFT OUTER JOIN PaymentCodes pc ON ppp.Client_Id = pc.Client_Id AND ppp.Project_Id = pc.Project_Id AND ppp.Payment_Code = pc.Payment_Code 
    LEFT OUTER JOIN PaymentTypes pt ON ppp.Client_Id = pt.Client_Id AND ppp.Project_Id = pt.Project_Id AND pt.Payment_Type = pc.Payment_Type 
    WHERE ppp.Client_Id = ar.Client_Id AND ppp.Project_Id = ar.Project_Id AND ppp.Person_Id = ar.Person_Id AND ppp.Line_Number IN (SELECT MAX(Line_Number) FROM PaymentsPerPerson WHERE Person_Id = ar.Person_Id)) AS Payment_Type, 
    ( 
    SELECT TOP 1 convert(varchar, Payment_Date, 120) AS Payment_Date FROM PaymentsPerPerson WHERE Client_Id = ar.Client_Id AND Project_Id = ar.Project_Id AND Person_Id = ar.Person_Id ORDER BY Line_Number DESC 
    ) AS Payment_Date, 
    ( 
    SELECT TOP 1 Card_Reference FROM PaymentsPerPerson WHERE Client_Id = ar.Client_Id AND Project_Id = ar.Project_Id AND Person_Id = ar.Person_Id ORDER BY Line_Number DESC 
    ) AS Transaction_Id, 
    convert(varchar, getdate(), 120) AS Date 
FROM 
    AccountingReport ar 
LEFT OUTER JOIN Participants pa ON ar.Client_Id = pa.Client_Id AND ar.Project_Id = pa.Project_Id AND ar.Person_Id = pa.Person_Id AND pa.Date_Registered IS NOT NULL 
LEFT OUTER JOIN Projects p ON ar.Client_Id = p.Client_Id AND ar.Project_Id = p.Project_Id 
RIGHT OUTER JOIN PaymentsPerPerson ppp ON ar.Client_Id = ppp.Client_Id AND ar.Project_Id = ppp.Project_Id AND ar.Person_Id = ppp.Person_Id 
WHERE 
    ar.Client_Id = 'CLIENTID' AND 
    ar.Project_Id = 'PROJECTID' AND 
    (IsNull(Old_Amount_Excl_VAT,0) <> 0 
    OR IsNull(Old_Amount_Incl_VAT,0) <> 0) 
    AND pa.Date_Registered IS NOT NULL 
ORDER BY 
    ar.Person_Id, 
    Item_Id, 
    SubItem_Id, 
    SubSubItem_Id 

내가 ROLLUP을 사용하여 시도했지만 이것이 내가 무엇을 얻을

Screenshot 2

이 내가 어떤 SQL 전문가는 아니지만 때문에, 좋은 것 롤업에게

SELECT 
    CASE WHEN (GROUPING(ar.Person_Id) = 1) THEN 0 
      ELSE ISNULL(ar.Person_Id, 'UNKNOWN') 
    END AS 'Id', 
    CASE WHEN (GROUPING(pa.Serial_Number) = 1) THEN 0 
      ELSE ISNULL(pa.Serial_Number, 'UNKNOWN') 
    END AS Serial_Number, 
    CASE WHEN (GROUPING(ar.Family_Name + ', '+ar.First_Name) = 1) THEN 'ALL' 
      ELSE ISNULL(ar.Family_Name + ', '+ar.First_Name, 'UNKNOWN') 
    END AS 'Name', 
    CASE WHEN ar.Line_Type = 'A' THEN 'Activity: '+ar.Item_Name ELSE 'Hotel: '+ar.Item_Name END AS 'Description', 
    SUM(CAST(IsNull(ar.Old_Amount_Excl_VAT,0) AS DECIMAL(10,2))) AS 'Amount Excl VAT', 
    SUM(CAST(IsNull(ar.Old_Amount_Incl_VAT,0) AS DECIMAL(10,2))) AS 'Amount Incl VAT', 
    SUM(CAST(IsNull(ar.Old_Amount_Incl_VAT,0) - IsNull(ar.Old_Amount_Excl_VAT,0) AS DECIMAL(10,2))) AS 'VAT Amount', 
    CASE WHEN (GROUPING(p.Currency_Code) = 1) THEN 'ALL' 
      ELSE ISNULL(p.Currency_Code, 'UNKNOWN') 
    END AS Currency_Code, 
    ( 
     SELECT TOP 1 pt.Payment_Type + ' ' + pt.Description AS Payment_Type FROM PaymentsPerPerson ppp 
     LEFT OUTER JOIN PaymentCodes pc ON ppp.Client_Id = pc.Client_Id AND ppp.Project_Id = pc.Project_Id AND ppp.Payment_Code = pc.Payment_Code 
     LEFT OUTER JOIN PaymentTypes pt ON ppp.Client_Id = pt.Client_Id AND ppp.Project_Id = pt.Project_Id AND pt.Payment_Type = pc.Payment_Type 
     WHERE ppp.Client_Id = ar.Client_Id AND ppp.Project_Id = ar.Project_Id AND ppp.Person_Id = ar.Person_Id AND ppp.Line_Number IN (SELECT MAX(Line_Number) FROM PaymentsPerPerson WHERE Person_Id = ar.Person_Id) 
    ) AS Payment_Type, 
    ( 
     SELECT TOP 1 convert(varchar, Payment_Date, 120) AS Payment_Date FROM PaymentsPerPerson WHERE Client_Id = ar.Client_Id AND Project_Id = ar.Project_Id AND Person_Id = ar.Person_Id ORDER BY Line_Number DESC 
    ) AS Payment_Date, 
    ( 
     SELECT TOP 1 Card_Reference FROM PaymentsPerPerson WHERE Client_Id = ar.Client_Id AND Project_Id = ar.Project_Id AND Person_Id = ar.Person_Id ORDER BY Line_Number DESC 
    ) AS Transaction_Id, 
    CONVERT(varchar, GETDATE(), 120) AS Date 
FROM 
    AccountingReport ar 
LEFT OUTER JOIN Participants pa ON ar.Client_Id = pa.Client_Id AND ar.Project_Id = pa.Project_Id AND ar.Person_Id = pa.Person_Id AND pa.Date_Registered IS NOT NULL 
LEFT OUTER JOIN Projects p ON ar.Client_Id = p.Client_Id AND ar.Project_Id = p.Project_Id 
RIGHT OUTER JOIN PaymentsPerPerson ppp ON ar.Client_Id = ppp.Client_Id AND ar.Project_Id = ppp.Project_Id AND ar.Person_Id = ppp.Person_Id 
WHERE 
    ar.Client_Id = 'CLIENTID' AND 
    ar.Project_Id = 'PROJECTID' AND 
    (IsNull(Old_Amount_Excl_VAT,0) <> 0 
    OR IsNull(Old_Amount_Incl_VAT,0) <> 0) 
    AND pa.Date_Registered IS NOT NULL 
GROUP BY 
    ar.Client_Id, 
    ar.Project_Id, 
    ar.Person_Id, 
    pa.Serial_Number, 
    ar.Line_Type, ar.Item_Name, ar.Item_Id, ar.SubItem_Id, ar.SubSubItem_Id, 
    p.Currency_Code, 
    ar.Family_Name + ', '+ar.First_Name WITH ROLLUP 
ORDER BY 
    ar.Person_Id, 
    Item_Id, 
    SubItem_Id, 
    SubSubItem_Id 

어떤 아이디어를 사용하여 사용했던 쿼리입니다.

SQL Server로 할 수 있습니까? 또는이 스크립트를 생성하려면 (ASP, PHP) 스크립트가 필요합니까?

클라이언트가 버튼을 클릭 할 때 결과를 Excel 보고서로 내보내므로 SQL 쿼리로 수행 할 수 있으면 더 좋을 것입니다.

+1

이 문제를 해결하려면 sql을 사용해야합니까? 이 쿼리를 다른 곳에서 사용하려고한다고 가정합니다. 나는보고 도구가 좋은 일을 할 수있을 것 같아요 엑셀의 피벗 테이블도 작동하고 피벗 테이블은 SQL 쿼리를 기반으로하므로 필요에 따라 새로 고칠 수 있습니다. – user3973227

+0

그것은 SQL이어야합니다. 우리는 SQL 쿼리를 사용하여 Excel로 내 보냅니다. 이것은 꽤 많은 클라이언트가 사용하기 때문에 더 쉽게 사용할 수 있습니다. –

답변

1
WITH 
DataSet AS (
--Your original query. For simplicity, I hard-coded the results. 
    SELECT '4142722'AS ID, 1 AS Serial_Number, 'Name1' AS Name, 'Activity: Description' AS DESCRIPTION, 10000.00 AS AmountExclVAT,10000.00 AS AmountInclVAT, 0 AS VATAmount, 'EUR' AS Currency_Code, NULL AS Payment_Type, NULL AS Payment_Date, NULL AS Trasaction_ID, NULL as Date 
    UNION 
    SELECT '4142722'AS ID, 1 AS Serial_Number, 'Name1' AS Name, 'Activity: Description1' AS DESCRIPTION, 2000.00 AS AmountExclVAT,2000.00 AS AmountInclVAT, 0 AS VATAmount, 'EUR' AS Currency_Code, NULL AS Payment_Type, NULL AS Payment_Date, NULL AS Trasaction_ID, NULL as Date 
    UNION 
    SELECT '4142722'AS ID, 1 AS Serial_Number, 'Name1' AS Name, 'Activity: Description' AS DESCRIPTION, -1000.00 AS AmountExclVAT,-1000.00 AS AmountInclVAT, 0 AS VATAmount, 'EUR' AS Currency_Code, NULL AS Payment_Type, NULL AS Payment_Date, NULL AS Trasaction_ID, NULL as Date 
    UNION 
    SELECT '4142724'AS ID, 3 AS Serial_Number, 'Name2' AS Name, 'Activity: Description' AS DESCRIPTION, 5000.00 AS AmountExclVAT,5000.00 AS AmountInclVAT, 0 AS VATAmount, 'EUR' AS Currency_Code, NULL AS Payment_Type, NULL AS Payment_Date, NULL AS Trasaction_ID, NULL as Date 
    UNION 
    SELECT '4142724'AS ID, 3 AS Serial_Number, 'Name2' AS Name, 'Activity: Description' AS DESCRIPTION, 2000.00 AS AmountExclVAT,2000.00 AS AmountInclVAT, 0 AS VATAmount, 'EUR' AS Currency_Code, NULL AS Payment_Type, NULL AS Payment_Date, NULL AS Trasaction_ID, NULL as Date 
) 
, 
SubTotals AS (
    SELECT 
     ID 
     ,NULL AS SERIAL_NUMBER 
     ,NULL AS NAME 
     ,'Subtotal' DESCRIPTION 
     ,SUM(AmountExclVAT) sum_AmountExclVAT 
     ,SUM(AmountInclVAT) sum_AmountInclVAT 
     ,SUM(VATAmount) sum_VATAmount 
     ,NULL AS CurrencyCode 
     ,NULL AS Payment_Type 
     ,NULL AS Payment_Date 
     ,NULL AS Trasaction_ID 
     ,NULL as Date 
    FROM 
     DataSet 
    GROUP BY 
     ID 
     ,SERIAL_NUMBER 
     ,NAME 
) 
SELECT * FROM DataSet 
UNION 
SELECT * FROM SubTotals 
ORDER BY ID, DESCRIPTION 
+0

내가 원하는 것을하지 않습니다. 금액 (VAT), 부가가치세 (VAT) 및 부가가치세 (VAT) 금액의 3 개 항목에 대해 소계가 필요합니다. 이 두 개의 열을 추가하는 순간 동일한 합계를 가진 설명 행이 동일한 양을 제공합니다.따라서 3 줄의 설명이있는 경우 세 줄이 반복되지만 설명은 부분합으로 바뀝니다. –

+0

나는 쿼리를 업데이트했다. –

+0

감사합니다 !!! 그것이 내가 필요한 것입니다! –

0

person_id가 주어진 사람과 맞지 않는 경우 롤업에서 person_id 열을 사용할 필요가 없으며 롤업을 큐브로 변경하면 모든 특정 사람 이름에 대해서도 출력됩니다. 시도해주세요.

+0

죄송합니다, 무슨 말씀인지 모르겠군요. 롤업에서 성, 이름을 사용하고 있습니다. 그룹에서 person_id를 제거하면 오류가 발생합니다. 기본적으로 특정 인물에 대한 모든 기록이 표시되면 개인 당 지불 한 건당 하나의 기록을 얻은 다음 해당 개인에 대해 소계를 입력해야합니다. –

0

Frederico, WITH 문 (해당 NEEDS가 세미콜론으로 끝나기 전에 SQL 문)을 사용하여 Common Table Expression을 만들고 GROUP BY를 사용하는 부분 UNION ALL을 추가하고 부분합을 만듭니다. 나는 테이블 정의와 쿼리에서 누락 된 열 이름 BY 몇 가지 주문을하지 않았다 나는 완전히 그것을 테스트 할 수 있지만, 여기있다 :

; 

WITH Amounts (Id, Serial_Number, Name, Description, [Amount Excl VAT], [Amount Incl VAT], [VAT Amount], Currency_Code, Payment_type, Payment_Date, Transaction_Id, [Date]) 
    AS (
    SELECT 
    ar.Person_Id AS 'Id', 
    pa.Serial_Number, 
    ar.Family_Name + ', '+ar.First_Name AS 'Name', 
    CASE WHEN ar.Line_Type = 'A' THEN 'Activity: '+ar.Item_Name ELSE 'Hotel: '+ar.Item_Name END AS 'Description', 
    CAST(IsNull(ar.Old_Amount_Excl_VAT,0) AS DECIMAL(10,2)) AS 'Amount Excl VAT', 
    CAST(IsNull(ar.Old_Amount_Incl_VAT,0) AS DECIMAL(10,2)) AS 'Amount Incl VAT', 
    CAST(IsNull(ar.Old_Amount_Incl_VAT,0) - IsNull(ar.Old_Amount_Excl_VAT,0) AS DECIMAL(10,2)) AS 'VAT Amount', 
    p.Currency_Code, 
    ( 
    SELECT TOP 1 pt.Payment_Type + ' ' + pt.Description AS Payment_Type FROM PaymentsPerPerson ppp 
    LEFT OUTER JOIN PaymentCodes pc ON ppp.Client_Id = pc.Client_Id AND ppp.Project_Id = pc.Project_Id AND ppp.Payment_Code = pc.Payment_Code 
    LEFT OUTER JOIN PaymentTypes pt ON ppp.Client_Id = pt.Client_Id AND ppp.Project_Id = pt.Project_Id AND pt.Payment_Type = pc.Payment_Type 
    WHERE ppp.Client_Id = ar.Client_Id AND ppp.Project_Id = ar.Project_Id AND ppp.Person_Id = ar.Person_Id AND ppp.Line_Number IN (SELECT MAX(Line_Number) FROM PaymentsPerPerson WHERE Person_Id = ar.Person_Id)) AS Payment_Type, 
    ( 
    SELECT TOP 1 convert(varchar, Payment_Date, 120) AS Payment_Date FROM PaymentsPerPerson WHERE Client_Id = ar.Client_Id AND Project_Id = ar.Project_Id AND Person_Id = ar.Person_Id ORDER BY Line_Number DESC 
    ) AS Payment_Date, 
    ( 
    SELECT TOP 1 Card_Reference FROM PaymentsPerPerson WHERE Client_Id = ar.Client_Id AND Project_Id = ar.Project_Id AND Person_Id = ar.Person_Id ORDER BY Line_Number DESC 
    ) AS Transaction_Id, 
    convert(varchar, getdate(), 120) AS Date 
FROM 
    AccountingReport ar 
LEFT OUTER JOIN Participants pa ON ar.Client_Id = pa.Client_Id AND ar.Project_Id = pa.Project_Id AND ar.Person_Id = pa.Person_Id AND pa.Date_Registered IS NOT NULL 
LEFT OUTER JOIN Projects p ON ar.Client_Id = p.Client_Id AND ar.Project_Id = p.Project_Id 
RIGHT OUTER JOIN PaymentsPerPerson ppp ON ar.Client_Id = ppp.Client_Id AND ar.Project_Id = ppp.Project_Id AND ar.Person_Id = ppp.Person_Id 
WHERE 
    ar.Client_Id = 'CLIENTID' AND 
    ar.Project_Id = 'PROJECTID' AND 
    (IsNull(Old_Amount_Excl_VAT,0) <> 0 
    OR IsNull(Old_Amount_Incl_VAT,0) <> 0) 
    AND pa.Date_Registered IS NOT NULL 
) 
SELECT Id, 1 AS Level, Serial_Number, Name, Description, 
    [Amount Excl VAT], 
    [Amount Incl VAT], 
    [VAT Amount], 
    Currency_Code, Payment_type, Payment_Date, Transaction_Id, [Date] 
FROM Amounts 
UNION ALL 
SELECT Id, 2 AS Level, Serial_Number, Name, Description, 
    SUM([Amount Excl VAT]) AS [Amount Excl VAT], 
    SUM([Amount Incl VAT]) AS [Amount Incl VAT], 
    SUM([VAT Amount]) AS [VAT Amount], 
    Currency_code, Payment_type, Payment_Date, Transaction_Id, [Date] 
    FROM Amounts 
    GROUP BY Id, Serial_Number, Name, Description, currency_code, Payment_type, Payment_Date, Transaction_Id, [Date] 
ORDER BY 
    Id, 
    Level, 
    Item_Id, 
    SubItem_Id, 
    SubSubItem_Id 
+0

제안 해 주셔서 감사합니다. 방금 테스트했지만 모든 데이터가 두 번 나타납니다. 소계 없음 –

2

당신은 Excel로 수출하는 경우, 내가 생각하는 당신의 가장 좋은 방법은 첫 번째 쿼리에서 그대로 내보내고 Excel (데이터 메뉴 아래에 있음)에서 부분합을 활용하는 것입니다. Excel 또는 매크로 ("내보내기"버튼 클릭)를 통해 응용 프로그램 코드에서 자동화 할 수 있습니다.

+0

불가능, CSV로 내보내기. 매크로가 없습니다. –