0

2つの異なるテーブルから値を取得する2つの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|

私が探しているのは、タイムスタンプに基づいて2つのテーブルを結合し、最初のテーブルから2番目のテーブルを差し引くことです。したがって、次のようになります。

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

ありがとう!

4

2 に答える 2

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

答えを更新しました。ユニオンの最初の部分は、table2で一致するレコードがある場合とない場合で、テーブル内のすべてのレコードを返し、使用可能な場合はtable2カウントを減算します。ユニオンの2番目の部分は、カウント列に-1を掛けたテーブルに存在しないtable2のすべてのレコードを返します。

もっと簡単なアプローチがあるかもしれませんが、テーブルを本当に理解していなければ、これは私が提供できる最高のものです。残念ながら、MySQLは、UNIONの必要性を軽減する完全外部結合をサポートしていません。

于 2013-02-12T22:31:50.793 に答える
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)
于 2013-02-12T22:31:43.967 に答える