组合由同一列分组的两个GROUP BY查询

时间:2011-07-18 00:31:03

标签: mysql sql

我有一个交易表和一个标签表。我想得到按标签分组的事务表中所有事务的总和。有两种不同类型的交易:“预算”和“实际”

此查询将返回我想要的“预算”交易:

  SELECT tg.name as tag, SUM(amount) as budgetTotal 
    FROM transaction tx
    JOIN transaction_tag tt ON tt.transaction_id = tx.id
    JOIN tag tg ON tg.id = tt.tag_id
   WHERE tx.type = "budget"
     AND tx.date >= '2011-07-15' 
     AND tx.date < '2011-08-15'
GROUP BY tg.name

当然,“实际”交易的查询几乎相同:

  SELECT tg.name as tag, SUM(amount) as actualTotal 
    FROM transaction tx
    JOIN transaction_tag tt ON tt.transaction_id = tx.id
    JOIN tag tg ON tg.id = tt.tag_id
   WHERE tx.type = "actual"
     AND tx.date >= '2011-07-15' 
     AND tx.date < '2011-08-15'
GROUP BY tg.name

我的问题:如何将这两个查询的结果分组为一个,所以我得到一个包含三列的结果表:tag,budgetTotal和actualTotal?

3 个答案:

答案 0 :(得分:3)

试试这个:

  SELECT tg.name, 
         CASE WHEN tx.type = "actual" THEN SUM(amount) END AS actualTotal,
         CASE WHEN tx.type = "budget" THEN SUM(amount) END AS budgetTotal
  FROM....
  WHERE  tx.type IN ("actual", "budget")
  AND   ....
  GROUP BY tg.name

答案 1 :(得分:1)

SELECT tg.name as tag, SUM(amount) as budgetTotal, 'budget' as rectype
FROM transaction tx
JOIN transaction_tag tt ON tt.transaction_id = tx.id
JOIN tag tg ON tg.id = tt.tag_id
WHERE tx.type = "budget"
AND tx.date >= '2011-07-15' 
AND tx.date < '2011-08-15'
GROUP BY tg.name

UNION ALL

SELECT tg.name as tag, SUM(amount) as actualTotal, , 'actual' as rectype
FROM transaction tx
JOIN transaction_tag tt ON tt.transaction_id = tx.id
JOIN tag tg ON tg.id = tt.tag_id
WHERE tx.type = "actual"
AND tx.date >= '2011-07-15' 
AND tx.date < '2011-08-15'
GROUP BY tg.name

答案 2 :(得分:0)

不要忽略其他答案(这可能更好),但如果适合的话,这里是如何将它作为两个单独的行。此外,这个答案可以扩展到任意数量的tx.type而不更改查询(如果你删除了当然在where子句中对t.type的引用):

SELECT tg.name as tag, tx.type, SUM(amount) as total
    FROM transaction tx
    JOIN transaction_tag tt ON tt.transaction_id = tx.id
    JOIN tag tg ON tg.id = tt.tag_id
   WHERE tx.date >= '2011-07-15' 
     AND tx.date < '2011-08-15'
     AND tx.type in ("budget", "actual")
GROUP BY tg.name, tx.type;