我在mysql中有以下表格:
钱:
用户ID,日期,金额
费用:
用户ID,日期,金额
我需要一个sql语句(报告)与总数(存款 - 用户使用的金额)每周,以及按用户分组,一周
这是我到目前为止所做的:
SELECT expenses.userid AS user,
MONTH(expenses.date) AS month,
SUM(money.amount) AS amount_money,
SUM(expenses.amount) AS expenses_amount
FROM expenses INNER JOIN money ON money.userid = expenses.userid
GROUP BY 1,2 WITH ROLLUP
(星期一是一周的第一天)
示例数据:
钱:
2012-11-05 abustos 70000
2012-11-05 psepulveda 35000
2012-10-07 fmonsalves 45000
2012-09-07 abustos 55000
2012-09-07 abustos 50000
2012-08-09 abustos 100000
2012-08-21 csuarez 130000
2012-08-09 fmonsalves 100000
费用:
2012-05-24 csuarez 30000 2012-08-29 csuarez 30000 2012-08-22 csuarez 7990 2012-08-22 csuarez 21220 2012-08-23 csuarez 45577
我想要这样的事情:
用户:csuarez
周:19-08-2012 25-08-2012
钱:130000 费用:115898感谢您的帮助!
答案 0 :(得分:1)
请试试这个:
SELECT money.userid as user,
yearweek(expenses.date) as `week`,
sum(money.amount) as amount_money,
sum(expenses.amount) as expenses_amount,
sum(money.amount - expenses.amount) as deposit
FROM money
LEFT JOIN expense
ON money.userid = expenses.userid
group by `week`, money.userid;
根据eggyal的评论,您可以在mode
函数中使用week
来获取本周的第一个星期一。
Reference
SELECT money.userid as user,
week(expenses.date, 1) as `week`,
sum(distinct money.amount) as amount_money,
sum(distinct expenses.amount) as expenses_amount,
sum(money.amount - expenses.amount) as deposit
FROM money
LEFT JOIN expense
ON money.userid = expenses.userid
group by `week`, money.userid;
op提供样本数据后的更新:
答案 1 :(得分:1)
要获得周一“开始”一周的日期(从周一到周日运行的周数),您可以使用如下表达式:
mydate + INTERVAL IF(DAYOFWEEK(mydate)-1,2-DAYOFWEEK(mydate),-6) DAY
AS starting_monday
同样,要获得本周“结束”星期日的日期值:
mydate + INTERVAL IF(DAYOFWEEK(mydate)-1,8-DAYOFWEEK(mydate),0) DAY
AS ending_sunday
但这不是查询的问题,假设您的表money
代表帐户的存款(而不是余额),并且您的expenses
表表示从帐户中提款。< / p>
用户可能会有一周提款但没有存款,或者一周有存款且没有提款。在两个表上使用JOIN操作的查询可以排除行。而OUTER JOIN只能解决问题的一半。
根据您的描述,您真的想要一个包含所有提款和本周所有存款的查询。
一种方法是使用UNION ALL操作组合来自两个单独表的行:
SELECT 'm' AS m_or_e
, m.userid
, m.date
, m.amount
FROM money
UNION ALL
SELECT 'e'
, e.userid
, e.date
, -1.00*e.amount AS amount
FROM expenses
然后,您可以将该查询作为内联视图引用;但对于大型套装,那就是 由于创建了一个中间(派生)表,因此表现出有问题的表现。
这不太理想:
SELECT t.userid
, t.week_
, SUM(t.amount) AS total
, SUM(IF(t.source='m',t.amount,0)) AS amount_money
, SUM(IF(t.source='e',t.amount,0)) AS expenses_amount
FROM (
SELECT 'm' AS source
, m.userid
, YEARWEEK(m.date,1) AS week_
, SUM(m.amount) AS amount
FROM money m
GROUP BY m.userid, week_
UNION ALL
SELECT 'e' AS source
, e.userid
, YEARWEEK(e.date,1) AS week_
, -1.00*SUM(e.amount)
FROM expenses e
GROUP BY e.userid, week_
) t
GROUP BY t.userid, t.week_
对于这样的查询,理想情况下,“存款”和“取款”将记录在同一张表中,存款和取款存储为正数和负数,或者用于区分“金钱”和“费用”的标识符”
我也没有在其中任何一个表中看到主键或唯一键,但在userid,date
甚至userid,date,amount
上添加唯一约束可能会有问题。