2011-04-22 55 views
1

我正在使用一個相當多毛的存儲過程返回XML(XML用樣式錶轉換並打印到頁面;本質上是XML中的一個GridView) 。如果某個特定列的值不是兩個特定值之一(在這種情況下這些列未被彙總),我有要求將多行(當然具有相同的ID)彙總到一行中。如果列中有一個特定值,SQL中的聚合/組錶行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不變
  2. 聚集在XSLT,讓存儲過程不變
  3. 這不能與數據的方式實現當前正被返回(或不大量費時的解決方法是無法實現的)

EDIT

我面臨的問題之一是,記錄通常會有相同的ID字段,因此總計出現不正確的,因爲我總結了整個記錄(它計算了我想要的字段我不想要的字段)。

例如記錄可能是這樣的:

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

,我想最終的結果是這樣的:

1234 Shipment 175.00 
1234 Insurance 54.65 

發生的事情是這樣的:

1234 Shipment 229.65 
1234 Insurance 229.65 

,它將總計關閉。

我正在使用的策略是創建一個名爲「AggregateData」的CTE,它通過ID和Description來總結各種數量和組;這會失敗,因爲它給出了上述結果(每個描述的總和,所以該值出現兩次,並在報告上添加兩次)。我所得到的最接近的是不按描述分組,而是將其包裝在Max函數中(是的,我知道這不是一個好主意)。這給了我正確的總數,但描述不能準確地反映出來,例如有些記錄應該是「保險」,而是顯示「發貨」。

+0

可以像'GROUP BY CASE'('Insurance,Pickup')中的描述那麼customerID ELSE 1 END'起作用嗎?你有沒有保證的獨特的列,可以在你不想要任何分組的情況下使用? – 2011-04-22 13:58:15

+0

我不認爲你應該複製數據。 XSLT能夠做到這一點。 – 2011-04-22 15:49:22

+0

「運費」和「其他收費」說明如何轉化爲「運費」? – 2011-05-02 19:14:23

回答

5

最簡單的方法是寫兩個查詢和工會的結果

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

我認爲小組繼續進行Insurance/Pickup查詢......? – 2011-04-22 14:01:43

+0

這很奇妙。我唯一的問題是*可能*需要知道哪些行被組合在一起,哪些不是(顯示不同的描述) - 如果這確實最終成爲一個需求,我將如何處理? – 2011-04-22 14:10:06

+0

@Wayne M:你可以添加一個'IsGrouped'列。上面的查詢會像這樣改變:'select 1 as IsGrouped, ... union all選擇0作爲IsGrouped, ...'。 – 2011-04-22 15:53:57

0

也許是這樣的:

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 

您一定已經注意到了同樣的CASE表達式重複這裏兩次。您可以通過使用一個普通的子查詢避免:

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 

您可能還需要添加一些其他的列,如需要。

相關問題