0

クエリを作成するのに助けが必要です。これが私の現在のスキームです:

users:
+----+------------+
| id |  username  |
+----+------------+
| 1  |    rob     |
| 2  |    john    |
| 3  |    jane    | <--- jane never has donated
| 4  |    mike    | 
+----+------------+

donations:
+--------------------+------------+
|   uid   |  amount  |   date     |
+---------+----------+------------+
|    1    |    20    | 2013-10-10 | 
|    2    |    5     | 2013-10-03 | 
|    2    |    50    | 2013-09-25 |
|    2    |    5     | 2013-10-01 |
|    4    |    100   | 2012-10-01 | <-- past year
+---------+----------+------------+


Result I want:
+---------+-------------+---------+-------------+---------------+----------+ 
|    id   |   username  | amount  |   monthly   |  totalamount  |   total  |
+---------+-------------+---------+-------------+ --------------+----------+
|    1    |     rob     |   20    |      1      |       20      |     1    |
|    2    |     john    |   60    |      3      |       60      |     3    |
|    3    |     jane    |   0     |      0      |       0       |     0    |
|    4    |     mike    |   0     |      0      |       100     |     1    | 
+---------+-------------+-----------------------+---------------+----------+

これは私のクエリです:

SELECT
  u.*,
  COALESCE(sum(d.amount), 0) amount,
  COUNT(d.uid) monthly, 
  COUNT(d.amount) as Total, <-- need to get sum all time donations and number of times donated
FROM users u
LEFT JOIN donations d
  ON u.id = d.uid
    AND (month(d.date), year(d.date)) = (month(CURDATE()), year(CURDATE()))
GROUP BY u.id ORDER BY u.id ASC

したがって、同じデータから 2 つの異なる合計を追加する必要があります。

編集: http://sqlfiddle.com/#!2/20a974/9スキーマとデータ

どうすればこれを行うことができますか?

4

3 に答える 3

2

このためには、結合ではなく選択でデータをフィルタリングする必要があります。

この条件を削除します。

AND (month(d.date), year(d.date)) = (month(CURDATE()), year(CURDATE()))

これを選択に追加します:

SUM (CASE WHEN (month(d.date), year(d.date)) = (month(CURDATE()), year(CURDATE())) THEN 1 ELSE 0 END) as monthly

編集:

クエリ全体:

SELECT users.id, users.username, 
  COALESCE(sum(CASE WHEN (month(donations.date), year(donations.date)) = (month(CURDATE()), year(CURDATE())) THEN donations.amount ELSE 0 END), 0) monthly_sum, 
  COALESCE(sum(CASE WHEN (month(donations.date), year(donations.date)) = (month(CURDATE()), year(CURDATE())) THEN 1 ELSE 0 END), 0) monthly_amount, 

  COALESCE(sum(donations.amount), 0) total_sum, 
  count(*) total_amount

from users
left join donations
  on donations.uid = users.id
group by users.id, users.username

http://sqlfiddle.com/#!2/20a974/20/0

于 2013-10-25T22:14:22.243 に答える
1

私にとって、個別にグループ化された情報について考える最も簡単な方法は、それを個別のクエリに入れ、結果を結合することです。これはおそらく最も効率的ではありませんが、何かを機能させるのに役立ちます。

select auo.id, auo.username, 
  coalesce(monthly_count, 0), coalesce(monthly_total, 0),
  coalesce(total, 0), coalesce(total_amount, 0)
from aaa_users auo
left join  (
   select au.id as id, count(adm.amount) as monthly_count, SUM(adm.amount) as monthly_total
   from aaa_users au join aaa_donations adm on au.id = adm.uid and adm.donate_date > GETDATE()-30
   group by au.id
) as monthly on monthly.id = auo.id
left join (
   select au.id as id, count(ady.amount) total, SUM(ady.amount) as total_amount
   from aaa_users au join aaa_donations ady on au.id = ady.uid and ady.donate_date >  getDate()-450
   group by au.id 
) as yearly on yearly.id = auo.id

@CompuChipが言ったように、寄付テーブルに2回参加する方がきれいですが、ジョンの値が重複しているため、結合ロジックに問題があります。毎月の寄付と合計の寄付が合算されないようにするには、donons.id 列が必要になると思います。とにかく、正しく動作していませんが、ここに例があります

select au.id, au.username, 
    count(adm.amount), SUM(adm.amount) as monthly_total, 
    count(ady.amount), SUM(ady.amount) as total_amount
from aaa_users au 
left outer join aaa_donations adm on au.id = adm.uid and adm.donate_date > GETDATE()-60
left outer join aaa_donations ady on au.id = ady.uid and ady.donate_date > getDate()-450
group by au.id, au.username
order by au.id, au.username
于 2013-10-25T22:47:24.760 に答える
0

別のエイリアスを指定して、寄付に別の結合を行うことができます: LEFT JOIN 寄付 d2 on d2.uid = u.id. 次に、最後の 2 つのフィールドの d2.amount を合計します。

SELECT u.*, 
  COALESCE(sum(d.amount), 0) amount, 
  COUNT(d.uid) monthly, 
  COUNT(d.amount) as Total, 

  COALESCE(sum(d2.amount), 0) amountAll, 
  COUNT(d2.uid) monthlyAll,
  COUNT(d2.amount) as TotalAll

  FROM users u
     LEFT JOIN donations d ON u.id = d.uid AND (month(d.date), year(d.date)) = (month(CURDATE()), year(CURDATE()))
     LEFT JOIN donations d2 ON u.id = d2.uid 

 GROUP BY u.id ORDER BY u.id ASC
于 2013-10-25T21:59:41.913 に答える