サブクエリの使用
これを解決する 1 つの方法は、サブクエリを使用することです。 LEFT JOIN
右側のテーブルの一致ごとに新しい「結果」を作成するため、2 つの LEFT JOIN を使用すると、必要以上の行が作成されます。必要な値をサブ選択することもできますが、これは遅くなる可能性があります。
SELECT ta.id,
(SELECT SUM(total_sold) as total_sold
FROM table_b
WHERE date_sold BETWEEN ADDDATE(NOW(), INTERVAL -1 WEEK) AND NOW()
AND id=ta.id) as total_sold_this_week,
(SELECT SUM(total_sold) as total_sold
FROM table_b
WHERE date_sold BETWEEN ADDDATE(NOW(), INTERVAL -1 MONTH) AND NOW()
AND id = ta.id) as total_sold_this_month
FROM table_a ta;
結果:
+----+----------------------+--------------------- --+
| | ID | total_sold_this_week | total_sold_this_month |
+----+----------------------+--------------------- --+
| | 1 | 3 | 7 |
| | 2 | 4 | 4 |
| | 3 | ヌル | ヌル |
+----+----------------------+--------------------- --+
3行セット (0.04秒)
SUM(CASE ...) の使用
このメソッドはサブクエリを使用しません (また、大規模なデータ セットではより高速になる可能性があります)。「最大」の日付範囲を使用して table_a と table_b を一度結合し、次に aにSUM()
基づいCASE
て「より小さい範囲」を計算します。
SELECT ta.*,
SUM(total_sold) as total_sold_last_month,
SUM(CASE
WHEN date_sold BETWEEN NOW() - INTERVAL 1 WEEK AND NOW()
THEN total_sold
ELSE 0
END) as total_sold_last_week
FROM table_a AS ta
LEFT JOIN table_b AS tb
ON ta.id=tb.id AND tb.date_sold BETWEEN ADDDATE(NOW(),INTERVAL -1 MONTH) AND NOW()
GROUP BY ta.id;
これは、サブクエリの例とほぼ同じ結果セットを返します。
+----+-----------------------+-------------------- --+
| | ID | total_sold_last_month | total_sold_last_week |
+----+-----------------------+-------------------- --+
| | 1 | 7 | 3 |
| | 2 | 4 | 4 |
| | 3 | ヌル | 0 |
+----+-----------------------+-------------------- --+
3 行セット (0.00 秒)
唯一の違いは、0
代わりにNULL
. この方法を使用して必要な数の日付範囲を要約できますが、返される行をON
句の最大範囲に制限するのがおそらく最善です。
それがどのように機能するかを示すために: GROUP BY
and呼び出しを削除し、SELECT にSUM()
追加すると、次のように返されます。date_sold
+----+------------+--------------------------------------+------- ---------------+
| | ID | 販売日 | total_sold_last_month | total_sold_last_week |
+----+------------+--------------------------------------+------- ---------------+
| | 1 | 2010-04-30 | 2 | 2 |
| | 1 | 2010-04-24 | 2 | 0 |
| | 1 | 2010-04-24 | 2 | 0 |
| | 1 | 2010-05-03 | 1 | 1 |
| | 2 | 2010-05-03 | 4 | 4 |
| | 3 | ヌル | ヌル | 0 |
+----+------------+--------------------------------------+------- ---------------+
6行セット (0.00秒)
GROUP BY id
と2 つのtotal_soldSUM()
列を使用すると、結果が得られます。
古いアドバイス
2 つの異なる日付範囲を混在させる前に、GROUP BY
table1 のテーブル ID を使用してグループ化し、SUM()
集計関数を使用して返された行を合計することができました。
SELECT ta.id, SUM(tb.total_sold) as total_sold_this_week
FROM table_a as ta
LEFT JOIN table_b as tb
ON ta.id=tb.id AND tb.date_sold BETWEEN ADDDATE(NOW(),INTERVAL -3 WEEK) AND NOW()
GROUP BY ta.id
+----+----------------------+
| | ID | total_sold_this_week |
+----+----------------------+
| | 1 | 7 |
| | 2 | 4 |
| | 3 | ヌル |
+----+----------------------+
3 行セット (0.00 秒)
テストデータ
NOW()
は 2010 年 5 月 3 日です
mysql> select * from table_a; select * from table_b;
+----+
| | ID |
+----+
| | 1 |
| | 2 |
| | 3 |
+----+
3 行セット (0.00 秒)
+----+------------+------------+
| | ID | 販売日 | 総販売 |
+----+------------+------------+
| | 1 | 2010-04-24 | 2 |
| | 1 | 2010-04-24 | 2 |
| | 1 | 2010-04-30 | 2 |
| | 1 | 2010-05-03 | 1 |
| | 2 | 2010-05-03 | 4 |
+----+------------+------------+
5 行セット (0.00 秒)