簡體   English   中英

SQL查詢混合聚合結果和單個值

[英]SQL query mixing aggregated results and single values

我有一張交易表。 每個交易都有交易ID,會計期間(AP),過帳價值(PV)以及其他字段。 一些ID是重復的,通常是因為事務是錯誤完成的。 舉個例子,表的一部分可能如下所示:

ID    PV    AP  
123   100   2  
123   -100  5  

在這種情況下,交易在AP2中添加,然后在AP5中刪除。

另一個例子是:

ID    PV    AP  
456   100   2  
456   -100  5  
456   100   8

在第一個例子中,問題是,如果我正在分析在AP2中花費了什么,那么在那里有一個實際上不應該考慮的事務,因為它在AP5中再次被取出。 在第二個示例中,不應考慮后兩個事務,因為它們相互抵消。

我想標記盡可能多的交易,不應該將其視為錯誤的。 為了識別這些交易,我想找到具有重復ID的那些,其PV總和為零(如上面的ID 123)或最早的PV等於總和(PV)的交易,如第二個例子中所示。 這第二個條件是導致我悲痛的原因。

到目前為止我有

SELECT *
FROM table
WHERE table.ID IN (SELECT table.ID
                    FROM table
                    GROUP BY table.ID
                    HAVING COUNT(*) > 1
                    AND (SUM(table.PV) = 0
                    OR SUM(table.PV) = <PV of first transaction in each group>))
ORDER BY table.ID;

V形臂章是我正在嘗試做的事情,而且我被卡住了。 我可以這樣做,還是我可以在SQL中使用其他方法來執行此操作?

編輯1:順便說一句,我忘了說我正在使用SQL Compact 3.5,以防萬一。

編輯2:我認為上面的代碼片段有點誤導。 我仍然想要標記具有重復ID的事務,其中sum(PV)= 0,如第一個示例中所示。 但是,在最早的交易的PV = sum(PV)的情況下,如第二個例子中那樣,我實際想要的是保持最早的交易並用相同的ID標記所有其他交易。 對不起,如果這引起混亂。

編輯3:我一直在玩Clodoaldo的解決方案並取得了一些進展,但仍然無法得到我想要的東西。 我試圖讓我知道的交易肯定是錯誤的。 假設表中還包含以下事務:

ID     PV    AP  
789    100   2  
789    200   5  
789   -100   8

在這個例子中,sum(PV)<> 0和最早的PV <> sum(PV)所以我不想將這些中的任何一個標記出來。

如果我修改Clodoaldo的查詢如下:

    select t.*
    from 
    t
    left join (
        select id, min(ap) as ap, sum(pv) as sum_pv
        from t
        group by id
        having sum(pv) <> 0
    ) s on t.id = s.id and t.ap = s.ap and t.pv = s.sum_pv
     where s.id is null

這給出了結果

 ID      PV     AP
123      100    2
123     -100    5
456     -100    5
456      100    8
789      100    3
789      200    5
789     -100    8

雖然前4個交易都沒問題(它們會被標記出來),但789交易也在那里,我不想要它們。 但我無法弄清楚如何修改查詢,以便它們不被包括在內。 有任何想法嗎?

SQL小提琴

select t.* 
from 
    t
    inner join (
        select id, min(ap) as ap
        from t
        group by id
        having sum(pv) <> 0
    ) s on t.id = s.id and t.ap = s.ap

以上獲取有效交易。 如果你想要無效的,請使用:

select t.*
from 
    t
    left join (
        select id, min(ap) as ap
        from t
        group by id
        having sum(pv) <> 0
    ) s on t.id = s.id and t.ap = s.ap
where s.id is null

SQL小提琴

嘗試這樣的事情:

UPDATE
    Transactions
SET
    IsError = true
WHERE
    EXISTS
    (SELECT
        NULL
    FROM 
        Transactions SubsequentTransactions
    WHERE
        Transactions.ID = SubsequentTransactions.ID
    AND Transactions.AP < SubsequentTransactions.AP
    AND Transactions.PV = -1 * SubsequentTransactions.PV)

我認為這會奏效。 我根本沒有測試它,所以我建議你先在select語句中使用WHERE子句,以確保它只影響你想要的行。

除了第二個示例之外,這不會將負面交易標記為錯誤(您可能需要或可能不需要)。 在你的第二個例子中,有第三個記錄,如果它們被孤立地取消,它將取消第二個記錄。 你可能會發現你需要擴展邏輯以完全得到你需要的東西,但它應該讓你開始。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM