簡體   English   中英

MySQL-具有兩個關系的算術運算

[英]MySQL - Arithmetic operations with two relations

如何獲得每個客戶支付的總金額減去所收取的金額( em_paid_to )?

表客戶

cust_id INT
f_name VARCHAR
l_name VARCHAR
email VARCHAR
c_limit INT

表交易

id INT
em_paid_by VARCHAR
em_paid_to VARCHAR
amount INT
trans_date DATE

我已經嘗試過這樣做以獲取每個客戶支付的總價,但是它不起作用:

SELECT C.F_NAME, C.L_NAME, COUNT(T.EM_PAID_BY), SUM(T.AMOUNT)
FROM CUSTOMER C 
JOIN TRANSACTION T ON C.EMAIL = T.EM_PAID_BY;

...這將得出每個客戶收集的總數,仍然是相同的錯誤,我需要得到兩個結果之間的差額。

SELECT C.F_NAME, C.L_NAME, COUNT(T.EM_PAID_TO), SUM(T.AMOUNT)
FROM CUSTOMER C 
JOIN TRANSACTION T ON C.EMAIL = T.EM_PAID_TO;

我希望得到的像這樣的舊麥當勞oldmcdonald@gmail.com 2000(2000 + 4000 + 1000)-(2000 + 3000)= 2000

您現有的查詢會產生錯誤,因為它們使用聚合函數( SUM()COUNT() )而沒有GROUP BY子句來列出所有未聚合的列。

為了解決您的需求,一種解決方案是使用條件聚合:

  • 恢復在em_paid_toem_paid_by子句中出現客戶的電子郵件的所有交易
  • 按客戶分組(明智的選擇是將客戶標識添加到GROUP BY子句中,即使它不屬於結果)
  • 做有條件的數量和金額,這取決於是否記錄了上匹配em_paid_toem_paid_by

以下查詢為您提供詳細信息(付款至和付款金額,付款至和付款金額以及余額),您可以選擇與您相關的內容:

SELECT 
    c.f_name, 
    c.l_name, 
    SUM(c.email = t.em_paid_by) count_paid_by, 
    SUM(c.email = t.em_paid_to) count_paid_to, 
    SUM(CASE WHEN c.email = t.em_paid_by THEN t.amound ELSE 0 END) total_paid_by,
    SUM(CASE WHEN c.email = t.em_paid_to THEN t.amound ELSE 0 END) total_paid_to,
    SUM(CASE WHEN c.email = t.em_paid_by THEN t.amound ELSE -1 * t.amount END) balance
FROM 
    customer c 
    INNER JOIN transaction t
        ON c.email IN (t.em_paid_by, t.em_paid_to)
GROUP BY 
    c.cust_id, 
    c.f_name, 
    c.l_name
;

我將取消數據透視並進行匯總:

select t.email, c.fname, c.lname, sum(t.amount)
from ((select em_paid_by as email, -amount as amount
       from transaction t
      ) union all
      (select em_paid_to, amount
       from transaction t
      )
     ) t
group by email;

您可以加入customer表以獲取其他客戶信息:

select email, sum(amount)
from cusomer c join
     ((select em_paid_by as email, -amount as amount
       from transaction t
      ) union all
      (select em_paid_to, amount
       from transaction t
      )
     ) t
     on c.email = t.email
group by t.email, c.fname, c.lname;

我將在SELECT子句中使用相關子查詢:

select c.*,
    coalesce((
        select sum(amount)
        from transaction t
        where t.em_paid_by = c.email
    ), 0)
    -
    coalesce((
        select sum(amount)
        from transaction t
        where t.em_paid_to = c.email
    ), 0) as paid_balance
from customer c

如果您想要更多信息,例如事務計數,可以在FROM子句中使用子查詢:

select c.*,
    p.cnt_paid,
    r.cnt_received
    coalesce(p.sum_paid, 0) as sum_paid,
    coalesce(r.sum_received, 0) as sum_received,
    coalesce(p.sum_paid, 0) - coalesce(r.sum_received, 0) as paid_balance,
    p.cnt_paid + r.cnt_received as total_transactions
from customer c
left join (
    select em_paid_by as email, sum(amount) as sum_paid, count(*) as cnt_paid
    from transaction
    group by em_paid_by
) p on p.email = c.email
left join (
    select em_paid_to as email, sum(amount) as sum_received, count(*) as cnt_received
    from transaction
    group by em_paid_to
) r on r.email = c.email

暫無
暫無

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

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