MySQL show ranks of multiple columns - mysql

I have the table that looks like this:
Name Height Weight
Jim 60 150
Tom 62 170
Mac 64 160
I would like to find a query that returns something like this:
Name Height Weight Height_Rank Weight_Rank
Jim 60 150 3 3
Tom 62 170 2 1
Mac 64 160 1 2
What is the best way to show the ranks of multiple columns as I described above? I could use order by to find the rank of a single column but I would like to have the rank of multiple columns in a single table. Thanks!
EDIT:
The answer below is a good solution. However, if you are ranking thousands of rows you will likely run into a another problem. "group_concat" has a maximum length of 1024 bytes. You can increase this limit by running "SET SESSION group_concat_max_len = 1000000;". This will allow you to rank many more rows at once.

Use Some thing Like this..
SELECT Name,Height,Weight,FIND_IN_SET( Height,( SELECT GROUP_CONCAT( Height ORDER BY Height DESC ) FROM scores )) AS Height_Rank,FIND_IN_SET( Weight,( SELECT GROUP_CONCAT( Weight ORDER BY Weight DESC ) FROM scores ) ) AS Weight_Rank FROM scores

Related

Create new column storing average of rows from another column in MySQL

I am trying to create a new column that has stores the 'Average weight of the field'. For example, the answer for RaceID = 123 would be 54.5. The RaceID's are not organised from smaller to largest and are displayed randomly like the example below.
RaceID
Weight
No. Starters
123
56
2
124
58
2
123
53
2
125
60
2
125
51
2
124
62
2
Try below query, It will display current table data along with average column :
select t.*,
avg(Weight) over(partition by raceID order by raceID ) avg_raceID
from table t;
SELECT RaceID, AVG(Weight) AS val_1
FROM dataset_name
GROUP BY RaceID;
By using above code we can get the average value of weights for every unique RaceID. Check the below image for better understanding.
https://i.stack.imgur.com/kMA68.png
Let me know if there are any modifications or error.

How to get the lowest price from a particular group of users MYSQL

I have been at this for a few days without much luck and I am looking for some guidance on how to get the lowest estimate from a particular group of sullpiers and then place it into another table.
I have 4 supplier estimate on every piece of work and all new estimates go into a single table, i am trying to find the lowest 'mid' price from the 4 newsest entries in the 'RECENT QUOTE TABLE' with a group id of '1' and then place that into the 'LOWEST QUOTE TABLE' as seen below.
RECENT QUOTE TABLE:
suppid group min mid high
1 1 200 400 600
2 1 300 500 700
3 1 100 300 500
[4] [1] 50 [150] 300
5 2 1000 3000 5000
6 2 3000 5000 8000
7 2 2000 4000 6000
8 2 1250 3125 5578
LOWEST QUOTE TABLE:
suppid group min mid high
4 1 50 150 300
Any help on how to structure this would be great as i have been loking for a few days and have not been able to find anything to get me moving again, im using MYSQL and the app is made in Python im open to all suggestions.
Thanks in advance.
If you really want to select only row with group 1, you can do something like
INSERT INTO lowest_quote_table
SELECT * FROM recent_quote_table
WHERE `group` = 1
ORDER BY `mid` ASC
LIMIT 1.
If you want a row with the lowest mid from every group, you can do something like
INSERT INTO lowest_quote_table
SELECT rq.* FROM recent_quote_table AS rq
JOIN (
SELECT `group`, MIN(`mid`) AS min_mid FROM recent_quote_table
GROUP BY `group`
) MQ ON rq.`group` = MQ.`group` AND rq.`mid` = MQ.min_mid

How to query specific rows order by multiply result

I have a product table with commission column. I want to compare the product and sort by commission result. Is it possible to do so? Here I have :
id price com% (com)
3 3500 23 (805)
4 3800 23 (874)
30 3800 25 (950)
31 4000 25 (1000)
32 3500 22 (770)
According to the com column. I expect the result to sort from 31,30,4,3 and 1 accordingly. All I can thinking of is this query.
select * from excursion_db order by exc_com desc
Only sort by the commission (com column). Which may cause an error when there's a high com% but low price. Eventually the com might lower than the higher price but less com%.
So, how to get the specify row order by the sum of price*com% desc?
Please note that : The (com) column is not exists in the table. I write up here to compare the total commission.
Try this:
select * from excursion_db order by price * `com%` desc

Mysql pivot table (concat) misuse (processing time)

I want to pivot the example below, I'm using:
SELECT Person, GROUP_CONCAT( Var ) , GROUP_CONCAT( Val )
FROM table
GROUP BY Person
This works fine, but... it takes about 20 seconds per line and my table has +/- 2.500.000 records :-P
(BTW; the table below is an example, not the actual one)
id person Var Val
-------------------------------
1 Bob Height 185
2 Bob Weight 74
3 Bob Age 40
4 Hank Height 193
5 Hank Weight 90
6 Hank Age 45
7 Bert Height 180
8 Bert Weight 85
9 Bert Age 43
PS:
Besides an answer (what would make you awesome) I also would like to know what is 'wrong' with this example (makes you even more awesomer)
There's nothing wrong with it, except that I'd write it like this
SELECT Person, GROUP_CONCAT(CONCAT(Var, ': ', Val))
FROM table
GROUP BY Person
because when you split it up in two columns, you won't know which Val belongs to which Var.
Apart from that, do you have indexes defined on those columns? If not, play around to see which index works best, separate indexes for each column or compound indexes on person, var, val.

Limiting using WHERE instead of LIMIT

I want to select some rows with a specific filter, but don't limit if I don't get, at least, 40 rows.
It's a pseudo-example:
SELECT * FROM `table`
WHERE
SUM(1) < 40 OR
`age` > 18
It's similar to LIMIT, but LIMIT will consider the WHERE filter ever. I want to ignore the filter if I don't have at least 40 rows (but accept the firsts rows).
How I do that?
Edit: a lot of people had doubts what I really wanted.
This is an example:
ID AGE
1 10
2 20
3 30
4 10
5 20
6 30
7 10
I want to get the first 2 rows EVER. And only after at least two rows, get new rows that match the given conditions (WHERE).
For example: I want the first 2 rows more rows whose age is 30. The result would be equivalent to:
ID AGE
1 10 <first>
2 20 <second>
3 30 <conditional>
6 30 <conditional>
You can use an increasing variable #rownum to simulate the same functionality. However, this is much less efficient than limit because the server brings the filtered-out rows into memory and continuously performs the #rownum:=#rownum+1 calculation.
SELECT #rownum:=#rownum+1, t.*
FROM `table` t, (SELECT #rownum:=0) r
WHERE
#rownum <= 40 OR
`age` > 18