2013-02-12 47 views
0

我有兩個選擇語句從兩個不同的表中取值。 的select語句看起來像這樣MySQL如何根據日期添加/減去兩列?

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| 

謝謝!

回答

1

假設表A有你的主記錄,那麼這樣的事情應該工作:

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 

我已經更新了答案。聯合的第一部分返回table2中的所有記錄,包含或不包含table2中的所有記錄,並在可用時減去table2計數。該聯合的第二部分返回表2中不存在的所有記錄,將count列乘以-1。

可能有一個更簡單的方法,但沒有真正理解表格,這是我能提供的最好的。不幸的是,MySQL不支持完整的OUTER JOIN,這將減輕對UNION的需求。

+0

是的,在思考了一下之後,我才意識到table1中的某些值可能不存在於table1中。在這種情況下,它需要是一個負值。在這種情況下,我該如何使用「union」? – phz 2013-02-12 22:35:56

+0

@ user1484186 - 好,沒問題 - 給我一秒,我會更新答案:) – sgeddes 2013-02-12 22:36:38

+0

@ user1484186 - 更新 - 祝你好運! – sgeddes 2013-02-12 22:40:34

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)