How to count rows of different group of values in one SELECT - mysql

I have a table with data that has an indicator as a number, it is not an ID or foreign key. This number is repeated several times in the table.
I need to print all the rows with included incremental row number within the same indicator value, so 1 is there 2 times, 2 is there 3 times, 3 is there 1 time.
Desired output:
name | indicator | rownumber
a 1 1
b 1 2
c 2 1
d 2 2
e 2 3
f 3 1
I have found this solution to count the rows but I do not know how to reset the counter if the indicator is changed.
The query I have so far is but this is incrementally counting the rows
SELECT name, indicator,
#rownum := #rownum + 1 as row_number
FROM rownumtable
CROSS JOIN (SELECT #rownum := 0) r
ORDER BY name ASC
BUT it prints the row number - see it on SQL Fiddle
name | indicator | row_number
a 1 1
b 1 2
c 2 3
d 2 4
e 2 5
f 3 6
Is there a way how to reset the row_number counter for specific group of same values in the MySQL query?

SELECT name, indicator,
#rownum := case when #prevIndicator <> indicator then 1 else #rownum + 1 end as rownumber,
#prevIndicator := indicator
FROM rownumtable
CROSS JOIN (SELECT #rownum := 0, #prevIndicator := 0) r
ORDER BY name ASC
SQLFiddle demo

Related

MySQL Broken Rank

I have the following query which returns some event details, the number of votes and a rank.
SELECT e.guid,
e.name,
(SELECT COUNT(ev.event_vote_id)
FROM event_vote sv
WHERE ev.event_uid = s.guid) AS votes,
#curRank := #curRank + 1 AS rank
FROM event e, (SELECT #curRank := 0) r
ORDER BY votes DESC
It returns the correct details including votes but the rank is broken.
Actual Result
guid | name | votes | rank
def test2 2 2
abc test1 1 1
ghi test3 0 3
jkl test4 0 4
Expected Result
guid | name | votes | rank
def test2 2 1
abc test1 1 2
ghi test3 0 3
jkl test4 0 4
For some reason test1 has a higher rank than test2.
I assume I need to use a JOIN but i'm unsure on the syntax.
You have to calculate the votes first, then calculate the ranking.
SELECT T.*, #curRank := #curRank + 1 AS rank
FROM ( SELECT e.guid,
e.name,
(SELECT COUNT(ev.event_vote_id)
FROM event_vote sv
WHERE ev.event_uid = s.guid) AS votes
FROM event e
) as T
CROSS JOIN (SELECT #curRank := 0) r
ORDER BY votes DESC
You have wrong result because SELECT section occurs before ORDER section, so you already have a rank but not necessary match the order you get at the end.
Can read more about it here:
Order Of Execution of the SQL query

Get row number (like excel)

How would I get the row number of a mysql output, for example:
select * from table
name age
David 12
Frank 13
I want to get the row number, like so:
select *, row_num from table
row name age
1 David 12
2 Frank 13
The row number on the left -- 1 through 7 -- not a part of the data itself.
In mysql, you have to use User-Defined Variables.
SELECT #rowno := #rowno + 1 AS row_no, *
FROM table
CROSS JOIN (SELECT #rowno := 0) t
-- ORDER BY age

How to get top 10 row out of 100 and rank if each row having a rating in the range of 1 (Best) to 10 (Worst) in mysql

enter image description here
I want to sort top 10 codes on the basis of rating so that i can get result like below:
code|rating|rank
54383|4 | 1
24326|4 | 2
19580|6 | 3
use ORDER BY or limit
SELECT code, rating, #rownum := #rownum + 1 AS rank
From table, (SELECT #rownum := 0) r
ORDER BY rating DESC
limit 10

MYSQL - limit amount of records that exceed count size

I currently have a query that counts the 'parent_id' value for each row and adds it within each row.
For example, if I have 4 records that have the has the value '1432' under 'parent_id' it will show the count value 4 under the 'count' column.
I am trying to limit the amount of rows based on the count number.
For example, let's say we want to exceed the number of records per 'parent_id' to 2. if the 'parent_id' has reached the third record, it just passes on and it won't return that record.
Example of existing table:
ID parent_id count(parent_id)
1 1234 2
2 1234 2
3 3221 3
4 3221 3
5 3221 3
6 5432 1
7 4312 1
The result I'd like to get is:
ID parent_id count(parent_id)
1 1234 2
2 1234 2
3 3221 2
4 3221 2
5 5432 1
6 4312 1
This is a select per group query:
SELECT id, parent_id, rn
FROM (
SELECT #rn:=CASE WHEN #parent_id=parent_id
THEN #rn+1
ELSE 1
END AS rn
, #parent_id:=parent_id AS parent_id
, id
FROM t, (SELECT #rn:=0,#parent_id:='') AS u
ORDER BY parent_id,id
) as s
WHERE rn <= 2
FIDDLE
Mihai's answer may work, but it is not guaranteed to work. The problem is that MySQL does not guarantee the order of evaluation of expressions in the select. And, there are even occasions where it does not evaluate them in the expected order.
So, when using variables, it is safest to put all assignments in a single expression:
SELECT id, parent_id, rn
FROM (SELECT (#rn := if(#parent_id = parent_id, #rn + 1,
if(#parent_id := parent_id, 1, 1)
)
) as rn,
t.*
FROM t CROSS JOIN
(SELECT #rn := 0, #parent_id := '') params
ORDER BY parent_id, id
) t
WHERE rn <= 2;

Custom row numbering

I would like data rows numbered upon selecting from a table. Problem is that, I need not sequential numbering, but it should be numbered from 1 to 3 and so to the end, like below:
1 | first row
2 | second row
3 | third row
1 | fourth row
2 | and
3 | ....
1
2
3
I'm trying this query, but it does not work correctly:
mysql -> SET #n = 0;
-> SELECT
CASE
WHEN nnn = 3 THEN #n := 0
ELSE nnn
END
FROM (
SELECT #n := #n + 1 AS nnn FROM mytable
) AS t;
How to make it working correctly?
Adapted from this answer: With MySQL, how can I generate a column containing the record index in a table?
SELECT MOD(#curRow := #curRow + 1, 3) AS row_number
FROM mytable m
JOIN (SELECT #curRow := 0) r;
If you only need to select and assuming that there is column, say "id", that is sequential, then following query should help:
SELECT IF ((id%3) = 0, 3 , (id%3)) AS new_id, <other columns> FROM <table_name>;
Hope it helps...