2014-09-05 82 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

這是我一直在使用匯總

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中使用的查詢。

是否有可能做與SQL Server?或者我需要一些腳本(asp,php)來生成這個?

它會更好,如果它可以用SQL查詢來完成,因爲我們出口的結果是Excel報表當客戶端點擊一個按鈕。

+1

你必須使用sql來解決這個問題嗎?我假設你打算在其他地方使用這個查詢。我認爲一個報告工具可能會做得很好,在Excel中的數據透視表也可以工作,並且數據透視表可以基於sql查詢,因此您可以根據需要進行刷新。 – user3973227 2014-09-05 14:40:43

+0

它必須是SQL,我們使用SQL查詢導出爲ex​​cel。這被不少客戶使用,所以越容易越好。 – 2014-09-05 14:42:28

回答

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

不做我所需要的。我需要所有三欄的小計金額不含增值稅,金額包括增值稅和增值稅金額。當我添加這兩列時,它給了我相同數量的具有相同總計的描述行。所以如果我有3行描述,這三行會重複,但描述更改爲小計。 – 2014-09-08 11:37:48

+0

我更新了查詢。 – 2014-09-08 14:31:23

+0

謝謝!那正是我需要的! – 2014-09-08 15:49:36

0

如果爲person_id是針對一個特定的人那麼我們不需要使用在捲起爲person_id列,如果我們改變彙總向立方體我們會得到了把所有特定的人的名字爲好。請試試看。

+0

對不起,不知道你的意思。我在彙總中使用姓氏,名字。如果我通過它從組中刪除person_id會引發錯誤。基本上我應該得到一個記錄每個人每次付款,一旦一個特定的人的所有記錄已經顯示,然後把這個特定的人的小計。 – 2014-09-05 18:22:51

0

Frederico, 我使用WITH語句(以NEEDS以分號結尾之前的SQL語句)創建了公用表表達式,並添加了一個單獨的UNION ALL部分,該部分使用GROUP BY並創建小計。我不能完全測試,因爲我沒有得到表定義和一些ORDER 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

感謝您的建議。我只是測試它,但它給我所有的數據兩次。並且沒有小計 – 2014-09-05 16:31:08

2

如果要導出到Excel,我想你最好的辦法就是從第一個查詢中導出並在Excel中利用小計(在數據菜單下)。您可以通過Excel中的宏或應用程序代碼(點擊「導出」按鈕後)自動執行此操作。

+0

不可能,導出爲CSV。沒有宏。 – 2014-09-08 11:21:22