MySQL : Max value of combined columns - mysql

I need to return the highest value of two combined columns.
SELECT id, max(points1 + points2) as points from schema.table;
I want it to combine the two columns BEFORE looking for the highest value. What it seems to be doing is finding the highest value for points1, then the highest value for points2, and then combining them.
I hope that makes sense!
UPDATE WITH SAMPLE:
ID Points1 Points2
1 100 200
2 80 30
3 40 400
What max(points1 + points2) seems to be returning is a value of 500. What i'm hoping to see is a value of 440 -- which is the highest COMBINED value. Hopefully that makes more sense...

If I am understanding your post correctly, you are looking for:
SELECT id FROM schema.table
WHERE points1 + points2 = (SELECT MAX(points1 + points2) FROM schema.table)

You are looking for a pretty straightforward query:
SELECT id, point
FROM schema.table
INNER JOIN (SELECT MAX(points1 + points2) as point
FROM schema.table) q ON q.point=(points1+points2);

Another solution:
SELECT id, points1+points2 AS point FROM table ORDER BY point DESC LIMIT 1
without the LIMIT 1, you can get the full standings

Related

DIviding the SQL result into two halves

The SQL query is :
Select ProductName from Products;
The above query returns 5000 rows.
How can the result of 5000 rows be divided into two result sets of 2500 rows each,.i.e., one result set from 1 to 2500 and the other from 2501 to 5000?
Note:
Here ProductName is the primary Key.No ProductID column is present in the table.
It can be done either in the back end or in the front end.
An approach that works for mySQL (based on this answer https://stackoverflow.com/a/4741301/14015737):
Upper half
SELECT *
FROM (
SELECT test.*, #counter := #counter +1 counter
FROM (select #counter:=0) initvar, test
ORDER BY num
) X
WHERE counter <= round(50/100 * #counter);
ORDER BY num;
Lower half
Invert the sort order and remove the rounding
SELECT *
FROM (
SELECT test.*, #counter := #counter +1 counter
FROM (select #counter:=0) initvar, test
ORDER BY num DESC
) X
WHERE counter <= (50/100 * #counter);
ORDER BY num;
In case of an uneven number of records, the middle record is added to the upper half in this example. If you want it the other way around, move the round() to the other statement. If you don't want it at all, remove round().
Dbfiddle example: https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=fb70eae0f7f1434a24099b5bb19f0878
If you know the numbers that you want, just use limit:
select ProductName
from Products
order by id
And then either:
limit 2500
limit 2500 offset 2499
If you simply want the results split into half, then you can use:
select t.*
from (select t.*,
ntile(2) over (order by <primary key>) as tile
from t
) t
where tile = 1; -- or 2 for the other half
The easiest and probably fastest approach is to use the table's primary key if you are fine with getting the rows in its order.
Run
select productname, id from products order by id;
and fetch 2500 rows. Then with the last ID, say ID 3456, run
select productname, id from products where id > 3456 order by id;
and fetch 2500 rows again. Etc.
UPDATE: Seeing I got a downvote for this, I'll better explain :-)
The query returns 5000 rows now and the OP doesn't want that many rows, so they want to cut this in halves. But the query may well return 10000 rows next year. Will the OP suddenly be fine with getting 5000 rows at once? This doesn't seem likely. It is more likely that there is an amount of rows that shall not be surpassed. This is why I cut the amount into slices of 2500.
The other approach to number all rows and return the first n rows has a severe drawback: All rows must be read again. Even if it is decided to cut the result in chunks of 100 each, everytime all rows must be read, sorted, numbered, fetched from. Reading all rows from a table and sorting all these rows is a lot of work for a DBMS.

How to get Random of two specific numbers?

E.g.
The first number is: 429
The second number is: 529
So I want to write MySQL query in such a way that, it should give me either 429 or 529 exactly.
I searched on google regarding this, but its showing results for a random number as a range.
Any help will be appreciated.
EDIT
My real requirement is this:
INSERT INTO table1(table2_id, status, stage, added_by)
(SELECT id, 'Pending', 'Semifinal', RAND(SELECT 429 UNION SELECT 529) FROM table2)
SELECT * FROM (SELECT 429 UNION SELECT 529) AS tmp ORDER BY RAND() LIMIT 1
Steps:
Select 429 and 529
Apply random order
Return first result
The function is the following (without UNION and ORDER, only math and only one step):
(ROUND(RAND()) * 100) + 429
or
(FLOOR(0 + (RAND() * 2)) * 100) + 429
Refer to MySQL docs
APPENDED
To give a general answer to the question (to select one random integer from any two integers :x and :y):
(FLOOR(0 + (RAND() * 2)) * (:y - :x)) + :x
This way does not create a mem table and does not sort the rows in it and/or fetch one of the random rows.
Is this data placed within a table? Then something like this might work:
SELECT number FROM table ORDER BY rand() LIMIT 1

MySQL MAX from count query

I have table rozpis_riesitelov which contains columns :
id_rozpisu_riesit, id_zam, id_projektu, id_ulohy.
I made query :
select id_zam, id_ulohy, count(*) as counted
from rozpis_riesitelov
group by id_zam
having id_ulohy in (1,2,8)
which shows me id of employee (id_zam) and how many times He was in project (id_ulohy is irrevelant but I had to select it beacuse of having clause). It shows me everyone in db but I am looking for employee with ID of 4 who is in 6 projects (Yes, I could do order by but I want to see max). When I do max of this query like this:
select max(counted)
from (select id_zam, id_ulohy, count(id_zam) as counted
from rozpis_riesitelov
group by id_zam
having id_ulohy in (1,2,8)) as riesitel
which shows me number 149 instead of 6.
So basically I only need to find employee that occurs in the most of the projects.
What's wrong with sorting by the COUNT() value, and limiting to one result?
SELECT `id_zam`,
`id_ulohy`,
COUNT(*) AS `counted`
FROM `rozpis_riesitelov `
WHERE `id_ulohy` IN ( 1, 2, 8 )
GROUP BY `id_zam`
ORDER BY `counted` DESC
LIMIT 1
Not sure exactly what you are trying to accomplish but you only use HAVING to filter on your aggregate like this:
HAVING COUNT(*) > 1
you should be able to move the condition to a WHERE clause and get correct max returned:
select max(counted)
from (select id_zam, count(id_zam) as counted
from rozpis_riesitelov
where id_ulohy in (1,2,8)
group by id_zam) as riesitel

Counting rows in mysql database

I want to count from the row with the least value to the row with a specific value.
For example,
Name / Point
--------------------
Pikachu / 7
Voltorb / 1
Abra / 4
Sunflora / 3
Squirtle / 8
Snorlax / 12
I want to count to the 7, so I get the returned result of '4' (counting the rows with values 1, 3, 4, 7)
I know I should use count() or mysql_num_rows() but I can't think of the specifics.
Thanks.
I think you want this :
select count(*) from mytable where Point<=7;
Count(*) counts all rows in a set.
If you're working with MySQL, then you could ORDER BY Point:
SELECT count(*) FROM table WHERE Point < 7 ORDER BY Point ASC
If you want to know all about ORDER BY, check out the w3schools page: http://www.w3schools.com/sql/sql_orderby.asp
Just in case you want to only count the rows based on the Point values:
SELECT count(*) FROM table WHERE Point < 7 GROUP BY Point
This may help you to get rows falling between range of values :
select count(*) from table where Point >= least_value and Point<= max_value

MySQL: LIMIT by a percentage of the amount of records?

Let's say I have a list of values, like this:
id value
----------
A 53
B 23
C 12
D 72
E 21
F 16
..
I need the top 10 percent of this list - I tried:
SELECT id, value
FROM list
ORDER BY value DESC
LIMIT COUNT(*) / 10
But this doesn't work. The problem is that I don't know the amount of records before I do the query. Any idea's?
Best answer I found:
SELECT*
FROM (
SELECT list.*, #counter := #counter +1 AS counter
FROM (select #counter:=0) AS initvar, list
ORDER BY value DESC
) AS X
where counter <= (10/100 * #counter);
ORDER BY value DESC
Change the 10 to get a different percentage.
In case you are doing this for an out of order, or random situation - I've started using the following style:
SELECT id, value FROM list HAVING RAND() > 0.9
If you need it to be random but controllable you can use a seed (example with PHP):
SELECT id, value FROM list HAVING RAND($seed) > 0.9
Lastly - if this is a sort of thing that you need full control over you can actually add a column that holds a random value whenever a row is inserted, and then query using that
SELECT id, value FROM list HAVING `rand_column` BETWEEN 0.8 AND 0.9
Since this does not require sorting, or ORDER BY - it is O(n) rather than O(n lg n)
You can also try with that:
SET #amount =(SELECT COUNT(*) FROM page) /10;
PREPARE STMT FROM 'SELECT * FROM page LIMIT ?';
EXECUTE STMT USING #amount;
This is MySQL bug described in here: http://bugs.mysql.com/bug.php?id=19795
Hope it'll help.
I realize this is VERY old, but it still pops up as the top result when you google SQL limit by percent so I'll try to save you some time. This is pretty simple to do these days. The following would give the OP the results they need:
SELECT TOP 10 PERCENT
id,
value
FROM list
ORDER BY value DESC
To get a quick and dirty random 10 percent of your table, the following would suffice:
SELECT TOP 10 PERCENT
id,
value
FROM list
ORDER BY NEWID()
I have an alternative which hasn't been mentionned in the other answers: if you access from any language where you have full access to the MySQL API (i.e. not the MySQL CLI), you can launch the query, ask how many rows there will be and then break the loop if it is time.
E.g. in Python:
...
maxnum = cursor.execute(query)
for num, row in enumerate(query)
if num > .1 * maxnum: # Here I break the loop if I got 10% of the rows.
break
do_stuff...
This works only with mysql_store_result(), not with mysql_use_result(), as the latter requires that you always accept all needed rows.
OTOH, the traffic for my solution might be too high - all rows have to be transferred.