簡體   English   中英

顯示給定用戶的交易余額

[英]Showing balances of transactions for a given user

我有一種情況,我需要顯示每個用戶與其他用戶的余額。

表結構和虛擬數據腳本:

CREATE TABLE transactions (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    user1 INT NOT NULL,
    user2 INT NOT NULL,
    amount INT NOT NULL
);
INSERT INTO transactions VALUES(1, 1, 2, 10);
INSERT INTO transactions VALUES(2, 1, 3, 15);
INSERT INTO transactions VALUES(3, 4, 1, 25);
INSERT INTO transactions VALUES(4, 1, 5, 20);
INSERT INTO transactions VALUES(5, 5, 1, 18);
INSERT INTO transactions VALUES(6, 5, 1, 2);

結果:

在此處輸入圖片說明

現在我想總結 user = 1信息(余額)。 我想看到的結果是這樣的:

user    balance
2   10
3   15
4   -25
5   0

現在,我使用的是最新的穩定 MySQL 版本5.7.17-0ubuntu0.16.04.1 我有兩個問題:

  • MySQL 不支持FULL OUTER JOIN子句
  • MySQL 不支持WITH子句

我的手在這一點上被綁住了。 我想為上述情況編寫一個快速有效的查詢。 這是我的兩次嘗試(均無效):

這個不起作用,因為我不能使用FULL OUTER JOIN子句

SELECT IFNULL(t3.user, t4.user), IFNULL(t3.amount, 0) - IFNULL(t4.amount, 0)
FROM (
    select t1.user2 user, sum(t1.amount) amount
    from transactions t1
    where 1=1
        and t1.user1 = 1
    group by t1.user2
) t3
FULL OUTER JOIN (
    select t2.user1 user, sum(t2.amount) amount
    from transactions t2
    where 1=1
        and t2.user2 = 1
    group by t2.user1
) t4 ON t3.user = t4.user

這個不起作用,因為我不能使用WITH子句

WITH t3 AS
 (
    select t1.user2 user, sum(t1.amount) amount
    from transactions t1
    where 1=1
        and t1.user1 = 1
    group by t1.user2
),
t4 AS
(
    select t2.user1 user, sum(t2.amount) amount
    from transactions t2
    where 1=1
        and t2.user2 = 1
    group by t2.user1
)
SELECT
    t1.user,
    IFNULL(t3.amount, 0) - IFNULL(t4.amount, 0) balance
FROM t1
LEFT JOIN t3 ON t1.user = t2.user
UNION
SELECT t2.user FROM t1
RIGHT JOIN t3 ON t1.user = t2.user

更新

使用Gurwinder Singh提供的解決方案,我能夠在大約 500 萬行測試數據上測試這兩個查詢的性能(盡管 user1 = 1 或 user2 = 1 的數據數量遠少於此)。

在此處輸入圖片說明

和(與工會)

在此處輸入圖片說明

因此。 查詢 1快了 34% ((3.4-2.24)/3.4*100 = 34)。

請注意,此表上沒有索引。 稍后我將嘗試使用 MariaDB 進行相同類型的測試並比較結果。

更新 2

索引列后: user1user2amount情況發生了變化。

查詢 1 運行時間:

顯示第 0 - 2 行(共 3 行,查詢耗時 1.9857 秒。)

查詢2運行時間:

顯示第 0 - 2 行(共 3 行,查詢耗時 1.5641 秒。)

但我仍然認為這是一個很糟糕的結果。 也許我會放一些觸發器來更新余額到一個專用表中。 但在這一點上,答案已經有了答案。

您可以使用基於CASE的條件聚合:

嘗試這個:

select case 
        when user1 = 1
            then user2
        else user1
        end as user,
    sum(case 
            when user1 = 1
                then amount
            else - amount
            end) as amount
from transactions
where 1 in (user1, user2)
group by case 
        when user1 = 1
            then user2
        else user1
        end;

演示

或者兩步聚合:

select user, sum(amount) as amount
from (
    select user2 as user, sum(amount) as amount
    from transactions
    where user1 = 1
    group by user2

    union all

    select user1 as user, -sum(amount) as amount
    from transactions
    where user2 = 1
    group by user1
) t
group by user;

演示

暫無
暫無

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

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