MySQL Counting Records Cumulative per Day - mysql

I have a table that look like this:
S_ID | DATE
1 2016-01-01
1 2016-01-02
1 2016-01-02
1 2016-01-05
1 2016-01-05
2 2017-01-02
2 2017-01-04
2 2017-01-04
2 2017-01-04
2 2017-01-04
2 2017-01-05
I am trying, in a single query to have the result below (adding cumulatively the records in time)
DATE | S_ID 1 | S_ID 2
2016-01-01 | 1 | 0
2016-01-02 | 3 | 1
2016-01-03 | 3 | 1
2016-01-04 | 3 | 5
2016-01-05 | 5 | 6
Any suggestions?

Try this using group on date and conditional sum along with user variables to get cumulative sum.
Select date,
#s1 := #s1 + s_id_1 s_id_1,
#s2 := #s2 + s_id_2 s_id_2
From (select
date,
sum(s_id = 1) s_id_1,
sum(s_id = 2) s_id_2
from your_table
group by date
Order by date) t cross join (select #s1 := 0, #s2 :=0 ) t2;
It uses the fact that the true is 1 and false is 0 in mysql

You should better use
select
t.s_ID,
t.`date`,
(SELECT SUM(1) FROM table x WHERE x.`date` <= t.`date` AND x.S_ID = t.S_ID) AS cumulative_sum
from table t
group by s_ID,`date`;
This will not provide your desired result, but a form of the result which works independent of the number of users, while the information stays the same:
s_ID | DATE | cumulative_sum
1 2016-01-01 1
1 2016-01-02 3
1 2016-01-05 5
2 2016-01-02 1
2 2016-01-04 5
2 2016-01-05 6
(If there's no entry for an id/date pair, the count didn't change that day)

You can arrived this with a PREPARED Statement. The first Query will generate a query with all s_id in your table. You only must change YOYOURTABLE to your table name :
see the sample
CONCAT('SELECT `date`,'
,GROUP_CONCAT(f1)
,' FROM YOURTABLE GROUP BY DATE')
INTO #myquery
FROM (
SELECT DISTINCT CONCAT('sum(s_id = ',s_id,') AS sid_',s_id) AS f1
FROM yourtable
) tab1;
-- ONLY for Test to verify the Query
SELECT #myquery;
PREPARE test FROM #myquery;
EXECUTE test;
DEALLOCATE PREPARE test;
sample
mysql> SELECT * FROM yourtable;
+------+------------+
| s_id | date |
+------+------------+
| 1 | 2016-01-01 |
| 1 | 2017-02-02 |
| 2 | 2017-01-05 |
| 4 | 2016-03-04 |
| 7 | 2016-12-12 |
+------+------------+
5 rows in set (0,01 sec)
mysql> SELECT
-> CONCAT('SELECT `date`,'
-> ,GROUP_CONCAT(f1)
-> ,' FROM YOURTABLE GROUP BY DATE')
-> INTO #myquery
-> FROM (
-> SELECT DISTINCT CONCAT('sum(s_id = ',s_id,') AS sid_',s_id) AS f1
-> FROM yourtable
-> ) tab1;
Query OK, 1 row affected (0,01 sec)
mysql> SELECT #myquery;
+----------------------------------------------------------------------------------------------------------------------------------------+
| #myquery |
+----------------------------------------------------------------------------------------------------------------------------------------+
| SELECT `date`,sum(s_id = 1) AS sid_1,sum(s_id = 2) AS sid_2,sum(s_id = 4) AS sid_4,sum(s_id = 7) AS sid_7 FROM YOURTABLE GROUP BY DATE |
+----------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0,00 sec)
mysql> PREPARE test FROM #myquery;
Query OK, 0 rows affected (0,00 sec)
mysql> EXECUTE test;
+------------+-------+-------+-------+-------+
| date | sid_1 | sid_2 | sid_4 | sid_7 |
+------------+-------+-------+-------+-------+
| 2016-01-01 | 1 | 0 | 0 | 0 |
| 2016-03-04 | 0 | 0 | 1 | 0 |
| 2016-12-12 | 0 | 0 | 0 | 1 |
| 2017-01-05 | 0 | 1 | 0 | 0 |
| 2017-02-02 | 1 | 0 | 0 | 0 |
+------------+-------+-------+-------+-------+
5 rows in set (0,00 sec)
mysql> DEALLOCATE PREPARE test;
Query OK, 0 rows affected (0,00 sec)
mysql>

Related

How to apply case when with if condition in MySql

I have below mentioned two tables:
Table 1
ID Key
TTT-1 atre-0-1
TTT-2 atrt-4-2
TTT-3 attr-1-3
TTT-4 aert-2-5
Table2
Key Red1 Red2
atre-0-1 10 25
atre-0-1 15 07
atre-0-1 16 19
atrt-4-2 11 21
atrt-4-2 07 22
attr-1-3 -4 3
attr-1-3 33 11
attr-1-3 50 45
aert-2-5 -5 2
aert-2-5 -4 1
By utilizing the above tow tables, I want to fetch the minimum value of Red1 and Red2 group by ID with the below mentioned condition.
For any ID if any Red1 and Red2 value is between -5 to 5 than consider the other values which are maximum of five, If there are only one entry available for a ID against which value is between range -5 to 5 than only consider -5 to 5 value for minimum criteria.
Required Output:
ID Number
TTT-1 07
TTT-2 07
TTT-3 11
TTT-4 -5
I have written below mentioned query, but it didn't work properly.
select t1.ID,
case when min(t2.Red1)<min(t2.Red2) then min(t2.Red1) else min(t2.Red2) End as `Number`
from Table1 t1
left join Table2 t2 on t1.key=t2.key
group by t1.ID;
The following query should solve this problem:
SELECT t1.ID,
CASE WHEN min(t2.Red1)<min(t2.Red2) THEN t2.min_red1 ELSE t2.min_red2 END AS
`Number`
FROM Table1 t1
LEFT JOIN
(
SELECT
key,
Red1
Red2
min(Red1) AS min_red1,
min(Red2) AS min_red2
FROM Table2 ) AS t2
ON t1.key=t2.key
GROUP BY t1.ID;
You can use the below SQL, here is the example as per your expectation.
Query:
SELECT
a.ID,
CASE
WHEN
LEAST(MIN(b.red1), MIN(b.red2)) BETWEEN - 5 AND 5
THEN
IFNULL(LEAST(MIN(CASE
WHEN red1 NOT BETWEEN - 5 AND 5 THEN red1
END),
MIN(CASE
WHEN red2 NOT BETWEEN - 5 AND 5 THEN red2
END)),
LEAST(MIN(b.red1), MIN(b.red2)))
ELSE LEAST(MIN(b.red1), MIN(b.red2))
END AS `Number`
FROM
table1 a
JOIN
table2 b ON a.key = b.key
GROUP BY a.ID;
Example:
mysql> create table table1(ID varchar(20),`key` varchar(20));
Query OK, 0 rows affected (0.23 sec)
mysql> insert into table1 values
-> ('TTT-1','atre-0-1'),
-> ('TTT-2','atrt-4-2'),
-> ('TTT-3','attr-1-3'),
-> ('TTT-4','aert-2-5');
Query OK, 4 rows affected (0.27 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql>
mysql> create table table2(`key` varchar(20),red1 int(5),red2 int(5));
Query OK, 0 rows affected (0.30 sec)
mysql> insert into table2 values
-> ('atre-0-1',10,25),
-> ('atre-0-1',15,07),
-> ('atre-0-1',16,19),
-> ('atrt-4-2',11,21),
-> ('atrt-4-2',07,22),
-> ('attr-1-3',-4,3),
-> ('attr-1-3',33,11),
-> ('attr-1-3',50,45),
-> ('aert-2-5',-5,2),
-> ('aert-2-5',-4,1);
Query OK, 10 rows affected (0.29 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql>
mysql> select * from table1;
+-------+----------+
| ID | key |
+-------+----------+
| TTT-1 | atre-0-1 |
| TTT-2 | atrt-4-2 |
| TTT-3 | attr-1-3 |
| TTT-4 | aert-2-5 |
+-------+----------+
4 rows in set (0.20 sec)
mysql> select * from table2;
+----------+------+------+
| key | red1 | red2 |
+----------+------+------+
| atre-0-1 | 10 | 25 |
| atre-0-1 | 15 | 7 |
| atre-0-1 | 16 | 19 |
| atrt-4-2 | 11 | 21 |
| atrt-4-2 | 7 | 22 |
| attr-1-3 | -4 | 3 |
| attr-1-3 | 33 | 11 |
| attr-1-3 | 50 | 45 |
| aert-2-5 | -5 | 2 |
| aert-2-5 | -4 | 1 |
+----------+------+------+
10 rows in set (0.21 sec)
mysql>
mysql> SELECT
-> a.ID,
-> CASE
-> WHEN
-> LEAST(MIN(b.red1), MIN(b.red2)) BETWEEN - 5 AND 5
-> THEN
-> IFNULL(LEAST(MIN(CASE
-> WHEN red1 NOT BETWEEN - 5 AND 5 THEN red1
-> END),
-> MIN(CASE
-> WHEN red2 NOT BETWEEN - 5 AND 5 THEN red2
-> END)),
-> LEAST(MIN(b.red1), MIN(b.red2)))
-> ELSE LEAST(MIN(b.red1), MIN(b.red2))
-> END AS `Number`
-> FROM
-> table1 a
-> JOIN
-> table2 b ON a.key = b.key
-> GROUP BY a.ID;
+-------+--------+
| ID | Number |
+-------+--------+
| TTT-1 | 7 |
| TTT-2 | 7 |
| TTT-3 | 11 |
| TTT-4 | -5 |
+-------+--------+
4 rows in set (0.28 sec)

trigger to update table contribution calculation using mysql

I need to calculate contribution base on project per developer
Contribution table
-------------------------------------------------------------
| id | projected | developer id | total hours | contribution|
-------------------------------------------------------------
| 1 | 1 | 1 | 25 | |
-------------------------------------------------------------
| 2 | 1 | 2 | 75 | |
-------------------------------------------------------------
| 3 | 2 | 1 | 10 | |
-------------------------------------------------------------
need to update same table with trigger after insert and update
expected result
Contribution table
-------------------------------------------------------------
| id | projected | developer id | total hours | contribution|
-------------------------------------------------------------
| 1 | 1 | 1 | 25 | 25% |
------------------------------------------------------------
| 2 | 1 | 2 | 75 | 75% |
-------------------------------------------------------------
| 3 | 2 | 1 | 10 | 100% |
-------------------------------------------------------------
calculation for the getting contribution
project 1 :
total hours = 25 + 75 = 100
contribution per developer = 25/100*100
= 25%
i need a trigger to get this result: but don't know how to get this
This is my trigger not getting error but contribution calculation not correct
CREATE TRIGGER `update_contribution` AFTER INSERT ON `tasks`
FOR EACH ROW BEGIN
IF NOT EXISTS
(SELECT p_id ,d_id
FROM contribution
WHERE
p_id = NEW.p_id
AND
d_id = NEW.d_id)
THEN
SET #old_total_dev_hours = (SELECT SUM(total_hours)
FROM contribution
WHERE p_id = NEW.p_id
GROUP BY p_id);
SET #total_hours1 = (SELECT (total_hours)
FROM contribution
WHERE d_id = NEW.d_id AND p_id = NEW.p_id
);
SET #dev_con = #total_hours1/#old_total_dev_hours*100 ;
SET #total_hours = new.hours + new.overtime;
INSERT INTO contribution
( p_id,
d_id,
hours,
overtime,
total_hours,
contribution
)
VALUES
(NEW.p_id,
NEW.d_id,
NEW.hours,
NEW.overtime,
#total_hours ,
#dev_con
);
ELSE
UPDATE contribution
SET
hours = hours + NEW.hours ,
overtime = overtime + NEW.overtime,
total_hours = hours + overtime,
contribution = #dev_con
WHERE
p_id = NEW.p_id
AND
d_id = NEW.d_id;
END IF;
END
This is my code in this code other calculation are working fine
contribution is not getting correctly!!
Here's an updated trigger that would replace the one from your previous question. It calculates
both values for the total_hours and contribution percentage.
DELIMITER |
CREATE TRIGGER update_hours AFTER INSERT ON tasks
FOR EACH ROW
BEGIN
SET #old_total_dev_hours = (SELECT SUM(hours + overtime)
FROM contribution
WHERE p_id == new.p_id && d_id == new.d_id
GROUP BY p_id,d_id);
SET #old_total_hours = (SELECT SUM(hours + overtime)
FROM contribution
WHERE p_id == new.p_id
GROUP BY p_id);
SET #total_hours = #old_total_dev_hours + new.hours + new.overtime;
SET #contrib_percent = (#old_total_dev_hours / #old_total_hours) * 100;
INSERT INTO contribution
( p_id,
d_id,
hours,
overtime,
total_hours,
contribution )
VALUES
(
NEW.p_id,
NEW.d_id,
NEW.hours,
NEW.overtime,
#total_hours,
#contrib_percent
);
END|
DELIMITER ;
Assuming tasks logs hours worked by developers on projects then 2 things can happen 1) there is no note that a developer has worked on a project in contribution 2) a developer has worked on a project and the hours he has worked need to updated in contribution. Both cases imply that all developer contributions need to be recalculated on each insert to tasks.
For example
drop table if exists t,contribution;
create table t(id int auto_increment primary key, developerid int, projectid int,hrs_normal int, hrs_overtime int);
create table contribution(id int auto_increment primary key, projectid int,
developerid int, hrs int, contribution decimal (6,3) default 0);
drop trigger if exists t;
delimiter $$
create trigger t after insert on t
for each row
begin
declare totalhours int default 0;
set totalhours = (select ifnull(sum(hrs),0) from contribution where projectid = new.projectid);
set totalhours = totalhours + ifnull(new.hrs_normal,0) + ifnull(new.hrs_overtime,0);
if not exists (select 1 from contribution where projectid = new.projectid and developerid = new.developerid) then
insert into contribution(projectid,developerid,hrs)
values
(new.projectid,new.developerid,ifnull(new.hrs_normal,0) + ifnull(new.hrs_overtime,0)
);
else
update contribution
set hrs = hrs + ifnull(new.hrs_normal,0) + ifnull(new.hrs_overtime,0)
where developerid = new.developerid and projectid = new.projectid;
end if;
update contribution
set contribution = (hrs / totalhours) * 100
where projectid = new.projectid;
end $$
delimiter ;
MariaDB [sandbox]> truncate table t;
Query OK, 0 rows affected (0.28 sec)
MariaDB [sandbox]> truncate table contribution;
Query OK, 0 rows affected (0.25 sec)
MariaDB [sandbox]> select * from t;
Empty set (0.00 sec)
MariaDB [sandbox]> select * from contribution;
Empty set (0.00 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> insert into t (developerid , projectid ,hrs_normal , hrs_overtime )
-> values
-> (1,1,10,0);
Query OK, 1 row affected (0.02 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----+-------------+-----------+------------+--------------+
| id | developerid | projectid | hrs_normal | hrs_overtime |
+----+-------------+-----------+------------+--------------+
| 1 | 1 | 1 | 10 | 0 |
+----+-------------+-----------+------------+--------------+
1 row in set (0.00 sec)
MariaDB [sandbox]> select * from contribution;
+----+-----------+-------------+------+--------------+
| id | projectid | developerid | hrs | contribution |
+----+-----------+-------------+------+--------------+
| 1 | 1 | 1 | 10 | 100.000 |
+----+-----------+-------------+------+--------------+
1 row in set (0.00 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> insert into t (developerid , projectid ,hrs_normal , hrs_overtime )
-> values
-> (1,1,10,0),(2,1,30,10);
Query OK, 2 rows affected (0.05 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----+-------------+-----------+------------+--------------+
| id | developerid | projectid | hrs_normal | hrs_overtime |
+----+-------------+-----------+------------+--------------+
| 1 | 1 | 1 | 10 | 0 |
| 2 | 1 | 1 | 10 | 0 |
| 3 | 2 | 1 | 30 | 10 |
+----+-------------+-----------+------------+--------------+
3 rows in set (0.00 sec)
MariaDB [sandbox]> select * from contribution;
+----+-----------+-------------+------+--------------+
| id | projectid | developerid | hrs | contribution |
+----+-----------+-------------+------+--------------+
| 1 | 1 | 1 | 20 | 33.333 |
| 2 | 1 | 2 | 40 | 66.667 |
+----+-----------+-------------+------+--------------+
2 rows in set (0.00 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> insert into t (developerid , projectid ,hrs_normal , hrs_overtime )
-> values
-> (1,1,10,0),(2,2,30,10);
Query OK, 2 rows affected (0.05 sec)
Records: 2 Duplicates: 0 Warnings: 0
MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----+-------------+-----------+------------+--------------+
| id | developerid | projectid | hrs_normal | hrs_overtime |
+----+-------------+-----------+------------+--------------+
| 1 | 1 | 1 | 10 | 0 |
| 2 | 1 | 1 | 10 | 0 |
| 3 | 2 | 1 | 30 | 10 |
| 4 | 1 | 1 | 10 | 0 |
| 5 | 2 | 2 | 30 | 10 |
+----+-------------+-----------+------------+--------------+
5 rows in set (0.00 sec)
MariaDB [sandbox]> select * from contribution;
+----+-----------+-------------+------+--------------+
| id | projectid | developerid | hrs | contribution |
+----+-----------+-------------+------+--------------+
| 1 | 1 | 1 | 30 | 42.857 |
| 2 | 1 | 2 | 40 | 57.143 |
| 3 | 2 | 2 | 40 | 100.000 |
+----+-----------+-------------+------+--------------+
3 rows in set (0.00 sec)
Note if the business rules are that a developers hours can amended in tasks you will also need and update trigger along the same lines.

How to use union for handling date from two different tables

I have two tables. First table stk
ITEMID | STOCK
--------------
Test1 | 10
Test2 | 15
Test3 | 12
and second table qty
ITEMID | DOCDATE | QTY
--------------------------
Test1 | 2/28/2017 | 5
Test2 | 2/28/2017 | 8
Test3 | 2/28/2017 | 6
I used this query
select itemid,stock,docdate,qty
from (
select itemid,stock,null docdate,0 qty from stk
union
select itemid,0 stock,docdate,qty from qty
)
group by itemid,stock,docdate,qty
order by 1
Output I get:
ITEMID | STOCK | DOCDATE | QTY
------------------------------
Test1 | 0 |2/28/2017 | 5
Test1 | 10 | | 0
Test2 | 0 |2/28/2017 | 8
Test2 | 15 | | 0
Test3 | 0 |2/28/2017 | 6
Test3 | 12 | | 0
but I want to have this output:
ITEMID | STOCK | DOCDATE | QTY
------------------------------
Test1 | 10 |2/28/2017 | 5
Test2 | 15 |2/28/2017 | 8
Test3 | 12 |2/28/2017 | 6
If you only want to consolidate rows coming from the two different tables then you can use this query:
select itemid, MAX(stock), MAX(docdate), MAX(qty)
from (
select itemid,stock,null docdate,0 qty from stk
union
select itemid,0 stock,docdate,qty from qty
) as t
group by itemid
order by 1
Demo here
If your only goal is to have that output, then you can just do this:
SELECT Q.ItemId, (SELECT S.stock FROM stk S ON S.ItemId = Q.ItemId) AS STOCK, Q.DocDate, Q.Qty FROM qty Q
I am using subqueries to connect the two tables on Id, and then I select the stock from Stk where the ItemId is the same as the ItemId from Qty.
Unions are vertical joins are horizontal. Perhaps something like this is required.
MariaDB [sandbox]> create table stk(ITEMID varchar(10), STOCK int);
Query OK, 0 rows affected (0.20 sec)
MariaDB [sandbox]> insert into stk values
-> ('Test1' , 10),
-> ('Test2' , 15),
-> ('Test3' , 12);
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [sandbox]>
MariaDB [sandbox]> drop table if exists qty;
Query OK, 0 rows affected (0.14 sec)
MariaDB [sandbox]> create table qty(ITEMID varchar(10), DOCDATE varchar(10) , QTY int);
Query OK, 0 rows affected (0.20 sec)
MariaDB [sandbox]> insert into qty values
-> ('Test1' , '2/28/2017' , 5),
-> ('Test2' , '2/28/2017' , 8),
-> ('Test3' , '2/28/2017' , 6),
-> ('Test1' , '3/28/2017' , 7),
-> ('Test2' , '3/28/2017' , 7),
-> ('Test3' , '3/28/2017' , 7);
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0
MariaDB [sandbox]>
MariaDB [sandbox]> select s.itemid,s.stock,
-> q.docdate,sum(q.qty) qty
-> from stk s
-> join qty q on q.itemid = s.itemid
-> group by s.itemid,s.stock,q.docdate
-> order by q.docdate, s.itemid,s.stock
->
-> ;
+--------+-------+-----------+------+
| itemid | stock | docdate | qty |
+--------+-------+-----------+------+
| Test1 | 10 | 2/28/2017 | 5 |
| Test2 | 15 | 2/28/2017 | 8 |
| Test3 | 12 | 2/28/2017 | 6 |
| Test1 | 10 | 3/28/2017 | 7 |
| Test2 | 15 | 3/28/2017 | 7 |
| Test3 | 12 | 3/28/2017 | 7 |
+--------+-------+-----------+------+
6 rows in set (0.00 sec)
Use JOIN to get result:
SELECT ITEMID ,STOCK,DOCDATE,QTY
FROM table1
JOIN table2 ON table1.ITEMID = table2.ITEMID

Make new column which is incremented by it's order

I need to make new column for my table Products -> called Order (new column). And using rails migration I need to add new column and instantly set it's order number, but it's need to be done by product_id.
What I mean I need something like:
product_id | order
1 ------------> 1
1 ------------> 2
1 ------------> 3
2 ------------> 1
2 ------------> 2
Is there a way of doing it?
EDIT :
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''order' = t1.'order'' at line 15:
update product_submissions t
join (
select
id,
product_id,
'order' from (
select id,
product_id,
#rn:= if(#prev = product_id,#rn:=#rn+1,1) as 'order',
#prev:=product_id
from product_submissions,
(select #rn:=0,#prev:=0)r
order by product_id,id
)x
)t1 on t1.id=t.id set t.'order' = t1.'order'
Consider the following
mysql> create table test (id int ,product_id int);
Query OK, 0 rows affected (0.14 sec)
mysql> insert into test values (1,1),(2,1),(3,1),(4,2),(5,2);
Now lets create the order
select
product_id,
`order` from (
select
product_id,
#rn:= if(#prev = product_id,#rn:=#rn+1,1) as `order`,
#prev:=product_id from test,(select #rn:=0,#prev:=0)r
order by product_id,id
)x ;
This will give you something as
+------------+-------+
| product_id | order |
+------------+-------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
+------------+-------+
Now lets use in update command, but before that lets add the column (in your case its already there)
mysql> alter table test add column `order` int ;
Query OK, 5 rows affected (0.29 sec)
mysql> select * from test ;
+------+------------+-------+
| id | product_id | order |
+------+------------+-------+
| 1 | 1 | NULL |
| 2 | 1 | NULL |
| 3 | 1 | NULL |
| 4 | 2 | NULL |
| 5 | 2 | NULL |
+------+------------+-------+
5 rows in set (0.00 sec)
Finally the update command
update test t
join (
select
id,
product_id,
`order` from (
select id,
product_id,
#rn:= if(#prev = product_id,#rn:=#rn+1,1) as `order`,
#prev:=product_id
from test,(select #rn:=0,#prev:=0)r
order by product_id,id
)x
)t1 on t1.id=t.id set t.`order` = t1.`order`
mysql> select * from test ;
+------+------------+-------+
| id | product_id | order |
+------+------------+-------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
+------+------------+-------+
5 rows in set (0.00 sec)

Mysql Group by second column if first column is equal?

I have a table that looks like this
id | rating
1 | 1
1 | 3
1 | 1
1 | 2
2 | 3
2 | 3
2 | 1
etc,you get the idea.
Anyway, I want to end up with this result set
id | rating | num
1 | 1 | 2
1 | 3 | 1
1 | 2 | 1
2 | 3 | 2
2 | 1 | 1
So, what I want to do is group the rating's together as long as the id is the same!
I thought I could just do group by id, rating and just assumed it would group only if both columns were the same, but it doesn't it groups if either column is the same so I end up with
id | rating | num
1 | 1 | 7
How can I solve this?
I don't understand the issue you are having. This query works for me:
select
id, rating, COUNT(rating) as num
FROM rating
GROUP BY id, rating
ORDER BY id, rating ASC;
And, just to be thorough, here is my entire test session:
mysql> create table rating (id int, rating int);
Query OK, 0 rows affected (0.04 sec)
mysql> insert into rating values (1,1),(1,3),(1,1),(1,2),(2,3),(2,3),(2,1);
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> select id, rating, COUNT(rating) as num FROM rating GROUP BY id, rating;
+------+--------+-----+
| id | rating | num |
+------+--------+-----+
| 1 | 1 | 2 |
| 1 | 2 | 1 |
| 1 | 3 | 1 |
| 2 | 1 | 1 |
| 2 | 3 | 2 |
+------+--------+-----+
5 rows in set (0.00 sec)
you could try
SELECT id,rating,COUNT(rating) AS num
FROM table1
GROUP BY id,rating
ORDER BY id ASC
SQLFiddle Demo
SELECT id,rating,count(rating) from table group by id,rating