按周分组的mysql帮助

时间:2013-01-14 15:03:35

标签: mysql sql date

我在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

感谢您的帮助!

2 个答案:

答案 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上添加唯一约束可能会有问题。