SQL:每个GROUP BY的增量

时间:2014-07-11 09:28:08

标签: mysql sql count group-by

我想要返回列出exerciseID的总次数,但要对其进行过滤,以便每个exerciseID每个日期只能增加一次。出于这个原因,我认为我不能做group by date

id | exerciseid | date
1  | 105        | 2014-01-01 00:00:00
2  | 105        | 2014-02-01 00:00:00
3  | 105        | 2014-03-11 00:00:00
4  | 105        | 2014-03-11 00:00:00
5  | 105        | 2014-03-11 00:00:00
6  | 127        | 2014-01-01 00:00:00
7  | 127        | 2014-02-02 00:00:00
8  | 127        | 2014-02-02 00:00:00

// 105 = 5 total rows but 3 unique
// 127 = 3 total rows but 2 unique

$db->query("SELECT exerciseid as id, sum(1) as total
            FROM `users exercises` as ue
            WHERE userid = $userid
            GROUP BY exerciseid
            ORDER BY date DESC");

当前输出:

Array
(
    [id] => 105
    [date] => 2014-05-06
    [total] => 5
)
Array
(
    [id] => 127
    [date] => 2014-05-06
    [total] => 3
)

正如您所看到的那样,它并没有合并date和exerciseid相同的行。

预期结果:

Array
(
    [id] => 105
    [date] => 2014-05-06
    [total] => 3
)
Array
(
    [id] => 127
    [date] => 2014-05-06
    [total] => 2
)

3 个答案:

答案 0 :(得分:1)

for V2.0问题:

select
        exerciseid
      , count(distinct date) as exercise_count
from user_exercises
group by
        exerciseid
;

| EXERCISEID | EXERCISE_COUNT |
|------------|----------------|
|         54 |              1 |
|         85 |              3 |
|        420 |              2 |

请参阅this sqlfiddle

答案 1 :(得分:0)

如果您想要计算群组中的群组数量:

$db->query("SELECT e.id as id, e.name, count(id) as total, ue.date
            FROM `users exercises` as ue
            LEFT JOIN `exercises` as e ON exerciseid = e.id
            WHERE ue.`userid` = $userid
            GROUP BY id ASC
            ORDER BY total DESC");

否则,如果您想要将之前的总数添加到其他内容中,请创建一个这样的过程(我认为我的程序中存在错误)

CREATE PROCEDURE name
DECLARE
  record your_table%ROWTYPE;
  nb int DEFAULT 0;
BEGIN

  FOR record IN SELECT e.id as id, e.name as name, count(id) as nbid, ue.date as date
        FROM `users exercises` as ue
        LEFT JOIN `exercises` as e ON exerciseid = e.id
        WHERE ue.`userid` = $userid
        GROUP BY id ASC
        ORDER BY total DESC  
  LOOP
  set nb := nb + record.nbid;
  SELECT record.id,record.name,nb,date;
  END LOOP;
END

问候 Dragondark De Lonlindil

答案 2 :(得分:0)

我认为你正在寻找一个总计。

| USERID |                         DATE |                NAME | RUNNINGSUM |
|--------|------------------------------|---------------------|------------|
|      1 |   May, 10 2014 00:00:00+0000 |            football |          1 |
|      1 |  June, 10 2014 00:00:00+0000 |            football |          2 |
|      1 |  July, 10 2014 00:00:00+0000 |            football |          3 |
|      1 |  July, 10 2014 00:00:00+0000 |            football |          4 |
|      1 |   May, 10 2014 00:00:00+0000 | Machine Bench Press |          5 |
|      1 |  June, 10 2014 00:00:00+0000 | Machine Bench Press |          6 |
|      1 | March, 10 2014 00:00:00+0000 |               salsa |          7 |

MySQL缺少像row_number()这样的函数,这使得这很简单,但是这里的方法实现了与userid分区的row_number()相当。

SELECT
       userid
     , date
     , name
     , RunningSum
FROM(
      SELECT  @row_num := IF(@prev_user = ue.userid, @row_num + 1 ,1) AS RunningSum
             , ue.userid
             , ue.date
             , e.name
             , @prev_user := ue.userid
      FROM user_exercises ue
      INNER JOIN exercises e ON ue.exerciseid = e.id
      CROSS JOIN (SELECT @row_num :=1, @prev_user :='') vars
      ORDER BY
               ue.userid
             , ue.date
             , ue.exerciseid
     ) x
ORDER BY
         userid
       , RunningSum

请参阅this sqlfiddle