MySQL如何根据日期加/减两列?

时间:2013-02-12 22:22:49

标签: mysql

我有两个select语句从两个不同的表中获取值。 select语句看起来像这样

SELECT year(timestamp) y, month(timestamp) m, count(id) c
FROM table
WHERE clause="foo"
GROUP BY year(timestamp), month(timestamp)

返回类似

的内容
|-y--|-m|c|
|2013|01|9|
|2013|02|9|
|2013|03|9|
|2013|04|9|

SELECT year(timestamp) y, month(timestamp) m, count(id) c
FROM table2
WHERE clause="foo"
GROUP BY year(timestamp), month(timestamp)

返回类似

的内容
|-y--|-m|c|
|2013|01|1|
|2013|03|1|
|2013|04|1|

我正在寻找的是根据时间戳加入两个表,并从第一个表中减去第二个表。所以看起来应该是这样的:

|-y--|-m|c|
|2013|01|8|
|2013|02|9|
|2013|03|8|
|2013|04|8|

谢谢!

2 个答案:

答案 0 :(得分:1)

假设TableA有你的主记录,那么这样的东西应该有效:

SELECT t.y, t.m, t.c - IFNULL(t2.c,0) c
FROM
(
    SELECT year(timestamp) y, month(timestamp) m, count(id) c
    FROM table
    WHERE clause="foo"
    GROUP BY year(timestamp), month(timestamp)
) t
LEFT JOIN (
    SELECT year(timestamp) y, month(timestamp) m, count(id) c
    FROM table2
    WHERE clause="foo"
    GROUP BY year(timestamp), month(timestamp)
) t2 ON t.y = t2.y AND t.m = t2.m
UNION 
SELECT t.y, t.m, (t.c * -1) c
FROM
(
    SELECT year(timestamp) y, month(timestamp) m, count(id) c
    FROM table2
    WHERE clause="foo"
    GROUP BY year(timestamp), month(timestamp)
) t
LEFT JOIN (
    SELECT year(timestamp) y, month(timestamp) m, count(id) c
    FROM table
    WHERE clause="foo"
    GROUP BY year(timestamp), month(timestamp)
) t2 ON t.y = t2.y AND t.m = t2.m
WHERE t2.y IS NULL
ORDER BY y, m

我已经更新了答案。 union的第一部分返回表中的所有记录,有或没有表2中的匹配,在可用时减去table2计数。 union的第二部分返回table2中表中不存在的所有记录,将count列乘以-1。

可能有一种更简单的方法,但如果没有真正了解表格,这是我能提供的最好的方法。不幸的是,MySQL并不支持FULL OUTER JOIN,这将减少对UNION的需求。

答案 1 :(得分:0)

您可以使用派生表

SELECT t1.y, t2.m, t1.c - t2.c AS c
FROM 
  (SELECT year(timestamp) y, month(timestamp) m, count(id) c
   FROM table
   WHERE clause='foo'
   GROUP BY year(timestamp), month(timestamp)) AS t1
LEFT OUTER JOIN
  (SELECT year(timestamp) y, month(timestamp) m, count(id) c
   FROM table2
   WHERE clause='foo'
   GROUP BY year(timestamp), month(timestamp)) AS t2
ON (t1.y, t1.m) = (t2.y, t2.m)

另一个解决方案是连接表并计算每个表中的不同行。假设id是每个表中的主键列,这可能有效:

SELECT YEAR(table.timestamp) AS y, MONTH(table.timestamp) AS m,
 COUNT(DISTINCT table.id) - COUNT(DISTINCT table2.id) AS c
FROM table
LEFT OUTER JOIN table2 ON table2.clause = 'foo' AND
  EXTRACT(YEAR_MONTH FROM table.timestamp) =
  EXTRACT(YEAR_MONTH FROM table2.timestamp)
WHERE table.clause='foo'
GROUP BY EXTRACT(YEAR_MONTH FROM table.timestamp)