SQL交叉表查询可以查看某些事务的总和

时间:2016-12-31 11:16:19

标签: mysql sql

我有一个包含汇款交易的SQL数据库表。我有4列:TransferID,付款人,收款人,金额

让我们说这是我的数据库表:

DatabaseTable

我可以创建一个交叉表查询,以查看每个人向他的每个伙伴发送了多少钱。结果将是这样的:

ResultOfCrosstabQuery

然而,我想看到的是每两个人之间的交易余额。例如,如果Peter向John发送了13美元,John向Peter发送了2美元,那么我希望看到11美元(和-11美元)作为交易的汇总结果,而不是13美元和2美元。结果看起来应该是这样的:
ResultTable

什么查询可以成功?

2 个答案:

答案 0 :(得分:1)

如上所述,使用TRANSFORM子句的动态pivot crosstab query是唯一一种在其他RDMS中不可用的MS Access SQL方法。由于OP已将MySQL后端表链接到MS Access前端应用程序,因此可以在MySQL数据上运行前端交叉表查询。

对于特定需求,请考虑加入匹配付款人收款人的汇总查询的源查询。然后在源查询上运行交叉表:

来源查询

SELECT m1.Payer, m1.Payee, (m1.SumAmount - m2.SumAmount) As NetTransfer
FROM 
  (SELECT t.Payer, t.Payee, Sum(t.Amount) AS SumAmount
   FROM Transfers t
   GROUP BY t.Payer, t.Payee) m1
INNER JOIN
  (SELECT t.Payer, t.Payee, Sum(t.Amount) AS SumAmount
   FROM Transfers t
   GROUP BY t.Payer, t.Payee) m2
ON m1.Payer = m2.Payee AND m1.Payee = m2.Payer

-- Payer    Payee   NetTransfer
-- John     Fred              2
-- Fred     John             -2
-- Peter    John             11
-- John     Peter           -11

交叉表查询 (语法仅在MS Access中有效)

TRANSFORM Sum(q.NetTransfer) AS SumOfNetTransfer
SELECT q.Payer
FROM SourceQueryQ q
GROUP BY q.Payer
PIVOT q.Payee;

-- Payer    Fred    John    Peter
-- Fred               -2    
-- John        2              -11
-- Peter              11    

当然,第一个查询也可以嵌套为交叉表中的派生表:

合并查询

TRANSFORM Sum(q.NetTransfer) AS SumOfNetTransfer
SELECT q.Payer
FROM 
   (SELECT m1.Payer, m1.Payee, (m1.SumAmount - m2.SumAmount) As NetTransfer
    FROM 
       (SELECT t.Payer, t.Payee, Sum(t.Amount) AS SumAmount
       FROM Transfers t
       GROUP BY t.Payer, t.Payee) m1
    INNER JOIN
      (SELECT t.Payer, t.Payee, Sum(t.Amount) AS SumAmount
       FROM Transfers t
       GROUP BY t.Payer, t.Payee) m2
    ON m1.Payer = m2.Payee AND m1.Payee = m2.Payer) q
GROUP BY q.Payer
PIVOT q.Payee;

注意:与任何Access查询一样,交叉表限制为255列,因此如果数据包含超过254个不同的付款人/收款人,请使用PIVOT...IN子句定义列:

PIVOT q.Payee IN ('Fred', 'John', 'Peter')

答案 1 :(得分:0)

透视查询应该可以解决问题:

SELECT Payer,
       SUM(CASE WHEN Payee = 'Peter' THEN Amount END) AS Peter,
       SUM(CASE WHEN Payee = 'John'  THEN Amount END) AS John,
       SUM(CASE WHEN Payee = 'Fred'  THEN Amount END) AS Fred
FROM yourTable
GROUP BY Payer

根据您使用的数据库,您可能可以利用一些内置的数据透视功能。此外,将输出格式化为货币,或使用破折号格式化无金额,将是特定于数据库的。