2012-02-28 54 views
0

您好我有一個過程,像這樣:TSQL - 聚合函數表達式上含集合錯誤

CREATE PROCEDURE dbo.DWS_PROG (
           @fromDate datetime = '2012-01-01', 
           @maxMoney money = 200, 
           @limit int = 200 
          ) 
AS 
SET NOCOUNT ON; 

SELECT TOP (@limit) 
    convert(int,P.P_ID) AS 'ID' 
    , max(convert(MONEY,isnull(P.NGp,P.NGz))) AS 'NG' 
    , max(convert(MONEY,(CASE WHEN D.Doc_Type = 0x0000000000000016 
           THEN Cash_PLN 
           ELSE 0 END))) AS 'Interests' 
    , (SELECT TOP 1 convert(VARCHAR, H.Data_zmiany,105) 
     FROM dbo.Pozew_Historia_Stanow H 
     WHERE H.P_ID = P.P_ID 
      AND H.Stan_nastepny_id = 0x000000000000000D /*PZ*/) AS 'Data Pozwu' 
    , max((CASE WHEN Sad_Id=0x0000000000000E08 
       THEN 'EL' 
       ELSE 'PA' END)) AS 'TYPE' 
    , max((CASE WHEN Cost_Name =0x0000000000000008 
       THEN convert(varchar, Pay_Date,105) 
       ELSE NULL END)) AS 'Data pierwszego kosztu wpisu sądowego' 
    , (SELECT TOP 1 convert(VARCHAR, H.Data_zmiany,105) 
     FROM dbo.Pozew_Historia_Stanow H 
     WHERE H.P_ID = P.P_ID 
      AND H.Stan_nastepny_id = 0x00000000000000DD /*EGZ-1*/) AS 'Data wszczęcia egzekucji' 
    , sum((CASE WHEN D.Doc_Type = 0x0000000000000003 
       AND D.Pay_Date >= @fromDate 
       AND D.Pay_Date < DATEADD(mm,DATEDIFF(mm,0,@fromDate) + 1,0) 
       THEN Cash_PLN 
       ELSE 0 END)) AS 'M0' 
FROM dbo.Pozew P 
JOIN dbo.Orders Z 
    ON Z.Orders_Id = P.Orders_Id 
JOIN dbo.Docs D 
    ON D.P_ID = P.P_ID 
WHERE ((P.NGp IS NOT NULL AND P.NGp < @maxMoney) OR (P.NGp IS NULL AND P.NGz < @maxMoney)) 
    AND P.Stan IN ('PZ-PORAŻKA','PZ-PORAŻ-UB','PZ-PSPPOR-SP','PZ-PSPPOR-UP','PZ-PSSSUK-UP','PZ-ZAPŁATA','EGZ-C-ROSZ-1','EGZ-C-ROSZ-2','EGZ-SUKCES-S','EGZ-ZAS-R','EGZ-NZAS-R','EGZ-BS-1C','EGZ-WSZP-1','EGZ-WSZP-2','EGZ-SPL') 
    AND (SELECT TOP 1 dbo.Docs.Pay_Date 
     FROM dbo.Docs 
     WHERE dbo.Docs.P_ID = P.P_ID 
      AND dbo.Docs.Cost_Name = 0x0000000000000008 
    ORDER BY dbo.Docs.Pay_Date) >= @fromDate 
GROUP BY P.P_ID 

這basicly工作正常,但我有一個錯誤。 在JOIN之前的最後一行中,我爲所有類型爲0x00 ... 03的文檔和Pay_date介於@param和param之間的月末之間進行結算。簡單和工程:)

但我必須與子查詢替換@fromDate:

SELECT TOP 1 dbo.Docs.Pay_Date 
    FROM dbo.Docs 
WHERE dbo.Docs.P_ID = P.P_ID 
    AND dbo.Docs.Cost_Name = 0x0000000000000008 
    AND dbo.Docs.Pay_Date >= @fromDate 
ORDER BY dbo.Docs.Pay_Date 

所以,對於每一個文件的查詢會第一時間與日期特定類型的付款,然後將總結從開始的所有款項這個日期到月底。

SUM應該是這樣的:

SUM((CASE WHEN D.Doc_Type = 0x0000000000000003 
      AND D.Pay_Date >= 
       (SELECT TOP 1 dbo.Docs.Pay_Date 
        FROM dbo.Docs 
       WHERE dbo.Docs.P_ID = P.P_ID 
        AND dbo.Docs.Cost_Name = 0x0000000000000008 
        AND dbo.Docs.Pay_Date >= @fromDate 
       ORDER BY dbo.Docs.Pay_Date) 

      AND D.Pay_Date < DATEADD(mm, DATEDIFF(mm, 0, 
       (SELECT TOP 1 dbo.Docs.Pay_Date 
       FROM dbo.Docs 
       WHERE dbo.Docs.P_ID = P.P_ID 
        AND dbo.Docs.Cost_Name = 0x0000000000000008 
        AND dbo.Docs.Pay_Date >= @fromDate 
       ORDER BY dbo.Docs.Pay_Date)) + 1,0) 
     THEN Cash_PLN 
     ELSE 0 END)) AS 'M0' 

但這樣做Management Studio中拋出一個錯誤後:

Cannot perform an aggregate function on an expression containing an aggregate or a subquery.

我試圖解決近2天。 任何想法?

對不起,不顯示錶的結構,但數據庫是太大了,我只需要一種方法來解決這個錯誤:)

我的表看起來像這樣: 表Pozew:ID,姓名等

表文檔:文檔ID,p_id的(從Pozew表鍵),DOC_TYPE,cost_name,pay_date,cash_PLN

而且樣本記錄看起來像這樣:

文檔:

1,1,15,8,'2011-02-04',400
1,1,3,5,'2011-02-09',0
1,1,3,5,'2011 -02-12' ,0
1,1,3,5, '2011-02-04',0

簡單的場景: 我們添加一條記錄到文件表說,我們有cost_name 1號文件= 0x8,則添加其他文檔,但Doc_Type = 0x3。

所以我們想要得到所有具有doc_Type = 0x3的文檔,並且在cost_name = 0x8的第一個文檔的創建日期和月末之間添加。 但是我們必須將他們分組爲每個Pozew_id。

對不起,我倒英語:/

我創建了一個簡單的查詢,將更加清楚地顯示我的問題:

DECLARE @fromDate varchar 
SET @fromDate = '2011-06-01' 
SELECT TOP 100 
sum((CASE WHEN D.Typ_dokumentu = 0x0000000000000003 
      AND D.Data_platnosci >= 
      (SELECT TOP 1 Data_platnosci 
      FROM Dokumenty 
      WHERE Pozew_Id = P.Pozew_Id 
      AND Nazwa_kosztu = 0x0000000000000008 
      AND Data_platnosci >= @fromDate 
      GROUP BY Pozew_Id) 
      AND Data_platnosci < DATEADD(mm,DATEDIFF(mm,0, 
      (SELECT TOP 1 Data_platnosci 
      FROM Dokumenty 
      WHERE Pozew_Id = P.Pozew_Id 
      AND Nazwa_kosztu = 0x0000000000000008 
      AND Data_platnosci >= @fromDate 
      GROUP BY Pozew_Id) 
      ) + 1,0) THEN Kwota_PLN ELSE 0 END)) AS 'M0' 
FROM 
Dokumenty D 
JOIN Pozew P 
    ON D.Pozew_Id = P.Pozew_Id 
WHERE 
((P.NGp IS NOT NULL 
AND 
P.NGp < 200) 
OR 
(P.NGp IS NULL 
AND 
P.NGz < 200)) 
AND 
P.Stan IN ('PZ-PORAŻKA','PZ-PORAŻ-UB','PZ-PSPPOR-SP') 
AND 
(SELECT TOP 1 
    dbo.Dokumenty.Data_platnosci 
FROM 
    dbo.Dokumenty 
WHERE 
    dbo.Dokumenty.Pozew_Id = P.Pozew_Id 
    AND 
    dbo.Dokumenty.Nazwa_kosztu = 0x0000000000000008 
ORDER BY 
    dbo.Dokumenty.Data_platnosci) >= @fromDate 
+0

對不起@Filip德沃思與格式混亂:/ – Misiu 2012-02-28 09:55:17

+0

不用擔心。在vg中gg = G。 – 2012-02-28 09:58:15

回答

0

豈不是可能有一個派生表在你的加盟商提供「第一每種類型的支付@fromDate後」,然後在你的選擇聲明與此相比較。

即衍生查詢類似

select p_id, min(pay_date) startDate 
from docs 
where cost_name = 0x0000000000000008 
    and pay_date >= @fromDate 
group by p_id 
order by pay_date 

您按付款從而獲得相應的起始日期的加盟派生表。

那麼你的總和:

sum((case when d.doc_type = 0x0000000000000003 
      and d.pay_date >= startDate 
      and month(d.pay_date) = month(startDate) 
      and year(d.pay_date) = year(startDate)) then cash_pln 
      else 0 end) as 'M0' 

注意我沒有嘗試這樣做,因此它可能不會是完全正確的,但希望它顯示的原則

+0

我已經完成了另一個包含來自您的查詢的記錄的表的聯接。它像一個魅力:) – Misiu 2012-02-29 11:03:39

+0

僞SQL是前進的方向!謝謝 – kaj 2012-02-29 11:53:47

0

我會把pay_date到一個變量,並與工作。畢竟這是一個不變的價值。

DECLARE @pay_date datetime 
SET @pay_date = (SELECT TOP 1 dbo.Docs.Pay_Date 
        FROM dbo.Docs 
        WHERE dbo.Docs.P_ID = P.P_ID 
        AND dbo.Docs.Cost_Name = 0x0000000000000008 
        AND dbo.Docs.Pay_Date >= @fromDate 
        ORDER BY dbo.Docs.Pay_Date) 

然後在查詢

AND D.Pay_Date >= @pay_date 
+0

感謝您的回答,但是(抱歉,如果這聽起來很愚蠢)如果我聲明瞭一個變量並如上使用它,我將使用pay_date大於@pay_date的所有記錄。我需要做的是爲每個文檔選擇pay_date。我將編輯我的帖子,以顯示我想完成什麼樣的邏輯:) – Misiu 2012-02-28 10:04:28

相關問題