Reputation: 6277
I'm wanting to return the total number of times an exerciseID
is listed, but filter it so each exerciseID
may only be increment once per a date. For this reason I believe I cannot do a 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");
Current Output:
Array
(
[id] => 105
[date] => 2014-05-06
[total] => 5
)
Array
(
[id] => 127
[date] => 2014-05-06
[total] => 3
)
As you can see it's not merging the rows where the date and exerciseid are the same.
Expected Result:
Array
(
[id] => 105
[date] => 2014-05-06
[total] => 3
)
Array
(
[id] => 127
[date] => 2014-05-06
[total] => 2
)
Upvotes: 0
Views: 142
Reputation: 35573
for V2.0 question:
select
exerciseid
, count(distinct date) as exercise_count
from user_exercises
group by
exerciseid
;
| EXERCISEID | EXERCISE_COUNT |
|------------|----------------|
| 54 | 1 |
| 85 | 3 |
| 420 | 2 |
see this sqlfiddle
Upvotes: 1
Reputation: 35573
I think you are seeking a running total.
| 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 lacks functions like row_number() that make this simple, but here is an approach that achieves the equivalent of row_number() partitioned by userid.
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
see this sqlfiddle
Upvotes: 0
Reputation: 1
If you want count how many group you have on group by :
$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");
else if you want take previous total for addition, create a procedure like this (I think there are errors in my procedure)
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
regards Dragondark De Lonlindil
Upvotes: 0